diff --git a/.claude/skills/custom-objects-update/PLAN.md b/.claude/skills/custom-objects-update/PLAN.md
new file mode 100644
index 0000000..65b009c
--- /dev/null
+++ b/.claude/skills/custom-objects-update/PLAN.md
@@ -0,0 +1,166 @@
+# Custom Objects Update Skill - Implementation Plan
+
+## Overview
+
+This skill (`/custom-objects-update`) fetches the latest custom object data from each active MDW tenant and updates the tenant documentation pages in `mintlify/tenants/`.
+
+## Design Decisions (Finalized)
+
+### 1. Tenant Discovery: Auto-scaffold missing tenants ✅
+
+**Approach:** Hybrid discovery with auto-scaffolding
+- **Primary:** Check known MDW tenant IDs from `dbt_project.yml` config
+- **Secondary:** Scan existing `mintlify/tenants/*.mdx` files
+- **Action:** For any tenant with BQ data but no docs → **auto-create both pages**
+
+This ensures new tenants are automatically documented without manual intervention.
+
+### 2. Object Descriptions: LLM-powered ✅
+
+**Approach:** Generate intelligent descriptions using:
+- Object name pattern analysis (`*_summary`, `obt_*`, `rpt_*`, etc.)
+- Dataset context (`customized_views`, `klaviyo`, `northbeam_data`)
+- DDL analysis when available (column names, aggregation patterns)
+
+Example outputs:
+- `orders_and_ads_summary` → "Aggregated daily summary joining order metrics with advertising spend data."
+- `dsp_native` → "Raw Amazon DSP advertising data containing campaign-level spend and performance metrics."
+
+### 3. Execution: Parallel with throttling ✅
+
+**Approach:** Run up to 5 concurrent BQ queries using `xargs -P 5`
+- Reduces total runtime from ~60s to ~15s for 20 tenants
+- Avoids BQ rate limiting with conservative concurrency
+- Graceful error handling for failed queries
+
+### 4. Git Integration: Report and wait ✅
+
+**Approach:** No automatic commits
+- Write all files
+- Display comprehensive summary with changes
+- Wait for user to review
+- User explicitly requests commit when ready
+
+## Data Flow
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ /custom-objects-update │
+├─────────────────────────────────────────────────────────────────┤
+│ │
+│ 1. DISCOVER TENANTS │
+│ ├── Known MDW tenant IDs (from config) │
+│ ├── Existing docs (scan tenants/*.mdx) │
+│ └── Compare → identify NEW tenants to scaffold │
+│ │
+│ 2. AUTO-SCAFFOLD NEW TENANTS │
+│ ├── Create {tenant_id}.mdx (overview page) │
+│ └── Create {tenant_id}/custom-objects.mdx (placeholder) │
+│ │
+│ 3. FETCH DATA (PARALLEL, 5 concurrent) │
+│ └── For each tenant: │
+│ Query: sm-{tenant}.sm_metadata.dim_tenant_custom_objects│
+│ - Filter: latest snapshot_at │
+│ - Filter: classification IN (tenant_dataset_custom, │
+│ tenant_or_legacy_in_standard_dataset) │
+│ │
+│ 4. TRANSFORM & GENERATE DESCRIPTIONS │
+│ ├── Group by dataset_id, aggregate stats │
+│ └── LLM-generate descriptions from name/DDL/context │
+│ │
+│ 5. WRITE FILES │
+│ ├── tenants/{tenant_id}/custom-objects.mdx │
+│ ├── tenants/{tenant_id}.mdx (if new) │
+│ └── tenants/README.md (update counts) │
+│ │
+│ 6. REPORT & WAIT │
+│ ├── Summary table: tenant, objects, status, changes │
+│ ├── List of files modified │
+│ └── Wait for user confirmation before any git ops │
+│ │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+## File Structure
+
+```
+mintlify/.claude/skills/custom-objects-update/
+├── SKILL.md # Main skill instructions (429 lines)
+└── PLAN.md # This design document
+```
+
+## Usage Examples
+
+```bash
+# Update all tenants
+/custom-objects-update
+
+# Update single tenant
+/custom-objects-update neurogum
+
+# Preview changes without writing
+/custom-objects-update --dry-run
+
+# List discovered tenants
+/custom-objects-update --list
+
+# Check for new tenants not yet documented
+/custom-objects-update --discover
+```
+
+## BigQuery Query
+
+```sql
+WITH latest_snapshot AS (
+ SELECT *,
+ ROW_NUMBER() OVER (
+ PARTITION BY dataset_id, object_name
+ ORDER BY snapshot_at DESC
+ ) as rn
+ FROM `sm-{tenant}.sm_metadata.dim_tenant_custom_objects`
+ WHERE classification IN (
+ 'tenant_dataset_custom',
+ 'tenant_or_legacy_in_standard_dataset'
+ )
+)
+SELECT
+ dataset_id,
+ object_name,
+ object_type,
+ CAST(job_count_180d AS INT64) as job_count_180d,
+ FORMAT_TIMESTAMP('%Y-%m-%d %H:%M', snapshot_at, 'America/New_York') as snapshot_at_est,
+ ddl
+FROM latest_snapshot
+WHERE rn = 1
+ORDER BY CAST(job_count_180d AS INT64) DESC
+```
+
+## Error Handling
+
+| Scenario | Action |
+|----------|--------|
+| BQ auth failure | Stop immediately, show auth instructions |
+| Table doesn't exist | Skip tenant, include in "Failed" report |
+| Empty results (0 objects) | Generate page with notice |
+| Network timeout | Retry once, then skip and report |
+| Invalid MDX characters | Escape for compatibility |
+| Parallel job fails | Collect error, continue with others |
+
+## Dependencies
+
+- `bq` CLI (BigQuery command-line tool)
+- `gcloud` CLI for authentication
+- Active GCP credentials with access to tenant projects
+- Write access to mintlify/tenants/ directory
+
+## Estimated Runtime
+
+- ~2-3 seconds per tenant query
+- ~15-20 seconds total with parallel execution (20 tenants)
+- Description generation adds ~1-2 seconds per tenant
+
+## Maintenance Notes
+
+- **New tenants:** Automatically discovered and scaffolded
+- **Churned tenants:** Manual cleanup needed (docs remain but data stops updating)
+- **Refresh frequency:** Run weekly or after major tenant onboarding
diff --git a/.claude/skills/custom-objects-update/SKILL.md b/.claude/skills/custom-objects-update/SKILL.md
new file mode 100644
index 0000000..73cc1d1
--- /dev/null
+++ b/.claude/skills/custom-objects-update/SKILL.md
@@ -0,0 +1,428 @@
+---
+name: custom-objects-update
+description: Fetch latest custom object data from MDW tenants and update documentation. Run periodically to keep tenant custom objects pages current.
+disable-model-invocation: true
+allowed-tools: Bash(bq *), Bash(gcloud *), Bash(jq *), Bash(date *), Bash(parallel *), Bash(xargs *), Read, Write, Glob, Grep
+---
+
+# Custom Objects Documentation Update
+
+Update tenant custom objects documentation by fetching the latest data from each tenant's BigQuery warehouse.
+
+## Prerequisites
+
+Before running, ensure:
+1. You have `bq` CLI installed and authenticated
+2. Your GCP credentials have access to tenant projects (`sm-{tenant}`)
+3. You're in the mintlify documentation directory
+
+Test authentication:
+```bash
+bq query --use_legacy_sql=false "SELECT 1"
+```
+
+## Arguments
+
+- No arguments: Update all tenants (full refresh)
+- `{tenant_id}`: Update only that specific tenant
+- `--dry-run`: Preview changes without writing files
+- `--list`: List discovered tenants only, no updates
+- `--discover`: Check for new tenants not yet documented
+
+## Workflow
+
+### Step 1: Discover ALL Tenants (Including New Ones)
+
+**Primary source:** Query MDW active tenants from dbt_project.yml config via BigQuery metadata.
+
+Run this discovery query to find all tenants with `dim_tenant_custom_objects` tables:
+
+```bash
+# Get list of active MDW tenant projects by checking which have the metadata table
+bq query --use_legacy_sql=false --format=json "
+SELECT
+ REPLACE(schema_name, 'sm-', '') as tenant_id
+FROM \`region-us\`.INFORMATION_SCHEMA.SCHEMATA_OPTIONS
+WHERE option_name = 'default_table_expiration_days'
+ AND schema_name LIKE 'sm-%'
+LIMIT 100
+" 2>/dev/null || echo "[]"
+```
+
+**Fallback approach:** Check each known project directly:
+
+```bash
+# Known MDW tenant IDs (from dbt_project.yml mdw_config.active_master_account_ids.v2)
+KNOWN_TENANTS=(
+ avenuez fluencyfirm catalina-crunch theperfectjean irestore-4
+ cpap neurogum zbiotics peoplebrandco guardian-bikes xcvi
+ elix-healing piquetea catchco lmnt pillar3cx lectronfuelsystems
+ upwrd kindpatches idyl
+)
+
+# For each, check if dim_tenant_custom_objects exists
+for tenant in "${KNOWN_TENANTS[@]}"; do
+ # Convert dashes to clean ID (some IDs have dashes, projects use them as-is)
+ project="sm-${tenant}"
+ if bq query --use_legacy_sql=false "SELECT 1 FROM \`${project}.sm_metadata.INFORMATION_SCHEMA.TABLES\` WHERE table_name = 'dim_tenant_custom_objects' LIMIT 1" &>/dev/null; then
+ echo "$tenant"
+ fi
+done
+```
+
+**Also scan existing docs:**
+```bash
+ls tenants/*.mdx 2>/dev/null | xargs -I{} basename {} .mdx | grep -v README | sort
+```
+
+**Compare and identify:**
+- Tenants with docs but no BQ data → Mark as potentially churned
+- Tenants with BQ data but no docs → **Auto-scaffold new docs**
+
+### Step 2: Auto-Scaffold Missing Tenant Documentation
+
+For any tenant discovered in BigQuery but missing documentation, create both files:
+
+**Create overview page** (`tenants/{tenant_id}.mdx`):
+
+```mdx
+---
+title: "{Display Name}"
+sidebarTitle: "{Display Name}"
+description: "Tenant documentation for {Display Name}"
+icon: "building"
+---
+
+
+This page is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Access your data warehouse directly
+
+
+ View tenant-specific tables and views
+
+
+ Explore SourceMedium data models
+
+
+ Get started with SourceMedium
+
+
+
+## Resources
+
+
+
+ Manage your data configuration
+
+
+ Learn to use your dashboards
+
+
+ Improve your attribution data
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| Project ID | `sm-{tenant_id}` |
+| Standard Dataset | `sm_transformed_v2` |
+| Tenant ID | `{tenant_id}` |
+```
+
+**Create directory and custom-objects page:**
+```bash
+mkdir -p tenants/{tenant_id}
+```
+
+Then proceed with normal custom objects generation.
+
+### Step 3: Fetch Custom Objects Data (Parallel Execution)
+
+Run queries in parallel for all tenants (max 5 concurrent to avoid rate limits):
+
+```bash
+# Create temp directory for results
+TMPDIR=$(mktemp -d)
+
+# Function to fetch single tenant
+fetch_tenant() {
+ local tenant_id="$1"
+ local outfile="$TMPDIR/${tenant_id}.json"
+
+ bq query --use_legacy_sql=false --format=json --max_rows=1000 "
+ WITH latest_snapshot AS (
+ SELECT *,
+ ROW_NUMBER() OVER (
+ PARTITION BY dataset_id, object_name
+ ORDER BY snapshot_at DESC
+ ) as rn
+ FROM \`sm-${tenant_id}.sm_metadata.dim_tenant_custom_objects\`
+ WHERE classification IN (
+ 'tenant_dataset_custom',
+ 'tenant_or_legacy_in_standard_dataset'
+ )
+ )
+ SELECT
+ dataset_id,
+ object_name,
+ object_type,
+ CAST(job_count_180d AS INT64) as job_count_180d,
+ FORMAT_TIMESTAMP('%Y-%m-%d %H:%M', snapshot_at, 'America/New_York') as snapshot_at_est,
+ ddl
+ FROM latest_snapshot
+ WHERE rn = 1
+ ORDER BY CAST(job_count_180d AS INT64) DESC
+ " > "$outfile" 2>/dev/null
+
+ if [ $? -eq 0 ]; then
+ echo "OK:${tenant_id}"
+ else
+ echo "FAIL:${tenant_id}"
+ fi
+}
+
+export -f fetch_tenant
+export TMPDIR
+
+# Run in parallel (5 at a time)
+echo "${TENANT_LIST[@]}" | tr ' ' '\n' | xargs -P 5 -I{} bash -c 'fetch_tenant "$@"' _ {}
+```
+
+### Step 4: Transform Data & Generate Descriptions
+
+For each tenant's JSON results:
+
+1. **Parse and group by dataset_id**
+2. **Calculate aggregates:**
+ - Object count per dataset
+ - Total job_count_180d per dataset
+3. **Sort:**
+ - Datasets by total jobs (descending)
+ - Objects within dataset by job_count (descending)
+
+**Generate LLM-powered descriptions:**
+
+For each object, analyze its name, type, dataset context, and DDL (if available) to generate a meaningful 1-2 sentence description. Consider:
+
+- **Object name patterns:**
+ - `orders_*` → Order-related data
+ - `*_daily` / `*_hourly` → Time-aggregated metrics
+ - `*_summary` → Aggregated summary
+ - `obt_*` → "One Big Table" denormalized view
+ - `rpt_*` → Report/dashboard data
+ - `stg_*` → Staging/intermediate data
+ - `dim_*` → Dimension table
+ - `fct_*` → Fact table
+ - `*_native` → Raw/native data from external source
+
+- **Dataset context:**
+ - `customized_views` → Custom views created for this tenant's specific needs
+ - `klaviyo` → Email/SMS marketing data from Klaviyo
+ - `northbeam_data` → Attribution data from Northbeam
+ - `sm_experimental` → Beta/experimental features
+ - `sm_transformed_v2` → Customizations to standard models
+
+- **DDL analysis (if available):**
+ - Key column names suggest purpose
+ - Aggregation patterns (SUM, COUNT, AVG)
+ - Join patterns indicate relationships
+
+**Example descriptions:**
+- `orders_and_ads_summary` → "Aggregated daily summary joining order metrics with advertising spend data. Key columns: date, sm_channel, new_customers, revenue."
+- `dsp_native` → "Raw Amazon DSP (Demand-Side Platform) advertising data. Contains campaign-level spend and performance metrics."
+- `rfm_table` → "RFM (Recency, Frequency, Monetary) customer segmentation analysis for targeting and personalization."
+- `customer_lifetime_aggregates` → "Lifetime value analysis aggregating customer revenue and acquisition costs by channel."
+
+### Step 5: Generate MDX Content
+
+Generate the custom-objects.mdx file:
+
+```mdx
+---
+title: "{Display Name} Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the {Display Name} data warehouse"
+icon: "database"
+---
+
+[← Back to {Display Name}](/tenants/{tenant_id}) | [Open sm-{tenant_id} in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-{tenant_id})
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for {Display Name}, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `{snapshot_timestamp} EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`{dataset_name}`](https://console.cloud.google.com/bigquery?project=sm-{tenant_id}&ws=!1m4!1m3!3m2!1ssm-{tenant_id}!2s{dataset_name}) | {count} | {total_jobs:,} |
+
+---
+
+## Objects by Dataset
+
+### {dataset_name}
+
+
+**Type:** {object_type} | **Queries (180d):** {job_count:,}
+
+{llm_generated_description}
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-{tenant_id}&ws=!1m5!1m4!4m3!1ssm-{tenant_id}!2s{dataset_name}!3s{object_name})
+
+```sql
+-- Preview data
+SELECT * FROM `sm-{tenant_id}.{dataset_name}.{object_name}` LIMIT 10;
+```
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| Project ID | `sm-{tenant_id}` |
+| Standard Dataset | `sm_transformed_v2` |
+| Tenant ID | `{tenant_id}` |
+
+
+For questions about this documentation, contact your SourceMedium team.
+
+```
+
+### Step 6: Tenant ID to Display Name Mapping
+
+| Tenant ID | Display Name |
+|-----------|--------------|
+| `avenuez` | Avenue Z |
+| `catalinacrunch` | Catalina Crunch |
+| `catalina-crunch` | Catalina Crunch |
+| `catchco` | Catch Co |
+| `cpap` | CPAP |
+| `elix-healing` | Elix Healing |
+| `elixhealing` | Elix Healing |
+| `fluencyfirm` | Fluency Firm |
+| `guardian-bikes` | Guardian Bikes |
+| `guardianbikes` | Guardian Bikes |
+| `idyl` | Idyl |
+| `idylus` | Idyl |
+| `irestore-4` | iRestore |
+| `irestore4` | iRestore |
+| `kindpatches` | Kind Patches |
+| `lectronfuelsystems` | Lectron Fuel Systems |
+| `lectron-fuel-systems1` | Lectron Fuel Systems |
+| `lmnt` | LMNT |
+| `neurogum` | Neuro Gum |
+| `peoplebrandco` | People Brand Co |
+| `pillar3cx` | Pillar 3CX |
+| `piquetea` | Pique Tea |
+| `theperfectjean` | The Perfect Jean |
+| `upwrd` | Upwrd |
+| `xcvi` | XCVI |
+| `zbiotics` | ZBiotics |
+
+**Fallback:** If tenant ID not in mapping:
+1. Check existing `{tenant_id}.mdx` frontmatter for `title` field
+2. Otherwise, title-case the ID (replace `-` with space, capitalize words)
+
+### Step 7: Write Files
+
+For each tenant:
+```bash
+mkdir -p tenants/{tenant_id}
+# Write custom-objects.mdx
+# Write overview {tenant_id}.mdx if it doesn't exist (auto-scaffold)
+```
+
+### Step 8: Update README.md
+
+Update `tenants/README.md` "Current Tenants" table with new object counts.
+
+Parse existing README, update the table rows, preserve other content.
+
+### Step 9: Report Summary and Wait for Confirmation
+
+After processing all tenants, provide a detailed summary:
+
+```markdown
+## Custom Objects Update Summary
+
+**Run completed at:** {timestamp}
+**Tenants processed:** {count}
+
+### Results by Tenant
+
+| Tenant | Objects | Datasets | Status | Changes |
+|--------|---------|----------|--------|---------|
+| neurogum | 46 | 5 | ✅ Updated | +2 new, -1 removed |
+| zbiotics | 120 | 8 | ✅ Updated | No changes |
+| newcustomer | 15 | 2 | 🆕 Scaffolded | New tenant |
+| emptyco | 0 | 0 | ⚠️ No objects | - |
+
+### New Tenants Discovered & Scaffolded
+- `newcustomer` - Created overview page and custom objects page
+
+### Failed Tenants
+| Tenant | Error |
+|--------|-------|
+| badtenant | Table sm_metadata.dim_tenant_custom_objects not found |
+
+### Files Modified
+- `tenants/neurogum/custom-objects.mdx`
+- `tenants/zbiotics/custom-objects.mdx`
+- `tenants/newcustomer.mdx` (NEW)
+- `tenants/newcustomer/custom-objects.mdx` (NEW)
+- `tenants/README.md`
+
+### Next Steps
+1. Review the changes above
+2. Run `mintlify dev` to preview locally (optional)
+3. Tell me to commit when ready, or request specific changes
+```
+
+**IMPORTANT:** After reporting, wait for user confirmation before any git operations. Do NOT auto-commit.
+
+## Error Handling
+
+| Scenario | Action |
+|----------|--------|
+| BQ auth failure | Stop immediately, show auth instructions |
+| Table doesn't exist for tenant | Skip tenant, include in "Failed" report |
+| Empty results (0 objects) | Generate page with notice, include in report |
+| Network timeout | Retry once, then skip and report |
+| Invalid characters in names | Escape for MDX compatibility |
+| Parallel job fails | Collect error, continue with others |
+
+## Dry Run Mode
+
+When `--dry-run` is passed:
+1. Perform all queries and transformations
+2. Show what files would be created/modified
+3. Show diff of changes for existing files
+4. Do NOT write any files
+5. Report as normal
+
+## Single Tenant Mode
+
+When a specific tenant ID is passed (e.g., `/custom-objects-update neurogum`):
+1. Only process that one tenant
+2. Skip discovery phase
+3. Report only for that tenant
diff --git a/.github/workflows/docs-quality.yml b/.github/workflows/docs-quality.yml
new file mode 100644
index 0000000..e3e49c0
--- /dev/null
+++ b/.github/workflows/docs-quality.yml
@@ -0,0 +1,142 @@
+name: Docs Quality Checks
+
+on:
+ pull_request:
+ branches: [master]
+ paths:
+ - '**/*.mdx'
+ - '**/*.md'
+ - 'docs.json'
+
+jobs:
+ quality:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ # Fail fast on broken/placeholder docs content
+ - name: Reject Empty MDX Files
+ run: |
+ empty="$(find . -type f -name '*.mdx' -size 0 -print)"
+ if [ -n "$empty" ]; then
+ echo "❌ Found empty .mdx files:"
+ echo "$empty"
+ exit 1
+ fi
+
+ - name: Reject Placeholder Text
+ run: |
+ if command -v rg >/dev/null 2>&1; then
+ search() { rg -n "\\bblah\\b" --glob='*.mdx'; }
+ else
+ search() { grep -RInw --include='*.mdx' 'blah' .; }
+ fi
+
+ if search; then
+ echo "❌ Found placeholder text ('blah') in docs"
+ exit 1
+ fi
+
+ - name: Reject Placeholder Links
+ run: |
+ if command -v rg >/dev/null 2>&1; then
+ search() { rg -n "\\]\\(\\{[^\\)]*\\}\\)" --glob='*.mdx'; }
+ else
+ search() { grep -RInE --include='*.mdx' '\\]\\(\\{[^)]*\\}\\)' .; }
+ fi
+
+ if search; then
+ echo "❌ Found placeholder links like ]({...}) in docs"
+ exit 1
+ fi
+
+ # Spell check - catches typos like "attribuion" -> "attribution"
+ - name: Spell Check
+ uses: codespell-project/actions-codespell@v2
+ with:
+ skip: "*.json,*.yml,*.yaml,*.png,*.jpg,*.svg"
+ ignore_words_list: "smcid,sourcemedium,hdyhau,utm,utms,cogs,ltv,roas,aov,cpa,cac,arpu,sku,skus,recharge,shopify,klaviyo,gorgias,returnly,yotpo,elevar,fermát,fermat,knocommerce,fairing,zigpoll,matrixify,looker,bigquery,bq"
+
+ # Broken link validation
+ - name: Link Check
+ uses: lycheeverse/lychee-action@v1
+ with:
+ args: >-
+ --verbose
+ --no-progress
+ --accept 200,204,301,302,403,429
+ --exclude-path node_modules
+ --exclude 'mailto:*'
+ --exclude 'tel:*'
+ --exclude 'https://airtable.com/*'
+ '**/*.mdx'
+ '**/*.md'
+ fail: true
+
+ # JSON syntax validation
+ - name: Validate docs.json
+ run: python3 -m json.tool docs.json > /dev/null && echo "✅ docs.json is valid JSON"
+
+ # Metadata + orphan detection (discoverability)
+ - name: Validate Page Metadata and Orphans
+ run: python3 scripts/docs_inventory.py
+
+ # Placeholder language guardrail
+ - name: Reject Placeholder Language
+ run: python3 scripts/docs_placeholder_lint.py
+
+ # dbt-backed column accuracy (via schema docs yaml blocks)
+ - name: Validate Column References
+ run: python3 scripts/docs_column_accuracy.py
+
+ # Navigation reference validation
+ - name: Validate Navigation References
+ run: |
+ python3 << 'EOF'
+ import json
+ import os
+ import sys
+
+ def extract_page_refs(obj, refs=None):
+ """Recursively extract all page references from navigation config."""
+ if refs is None:
+ refs = []
+
+ if isinstance(obj, str):
+ # Skip external URLs
+ if not obj.startswith('http'):
+ refs.append(obj)
+ elif isinstance(obj, list):
+ for item in obj:
+ extract_page_refs(item, refs)
+ elif isinstance(obj, dict):
+ for key, value in obj.items():
+ # Look inside tabs, groups, pages, and navigation
+ if key in ('tabs', 'pages', 'navigation', 'groups'):
+ extract_page_refs(value, refs)
+
+ return refs
+
+ with open('docs.json') as f:
+ config = json.load(f)
+
+ refs = extract_page_refs(config)
+ missing = []
+
+ for ref in refs:
+ # Accept both "path.mdx" and "path/index.mdx"
+ mdx_path = f"{ref}.mdx"
+ index_path = os.path.join(ref, "index.mdx")
+ if not os.path.exists(mdx_path) and not os.path.exists(index_path):
+ missing.append(mdx_path)
+
+ if missing:
+ print(f"❌ Found {len(missing)} missing navigation references:")
+ for m in missing[:20]: # Limit output
+ print(f" - {m}")
+ if len(missing) > 20:
+ print(f" ... and {len(missing) - 20} more")
+ sys.exit(1)
+
+ print(f"✅ All {len(refs)} navigation references are valid")
+ EOF
diff --git a/.github/workflows/mintlify-docs-update.yml b/.github/workflows/mintlify-docs-update.yml
new file mode 100644
index 0000000..149c236
--- /dev/null
+++ b/.github/workflows/mintlify-docs-update.yml
@@ -0,0 +1,28 @@
+name: Mintlify Documentation Update
+
+on:
+ push:
+ branches:
+ - master
+ workflow_dispatch:
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '20'
+
+ - name: Install Mintlify CLI
+ run: npm install -g mintlify
+
+ - name: Validate documentation
+ run: |
+ echo "Validating documentation at SHA: ${{ github.sha }}"
+ mintlify validate || echo "::warning::Mintlify validation had errors (see above). This may be pre-existing MDX issues."
+ continue-on-error: true
\ No newline at end of file
diff --git a/.github/workflows/ragie-index.yml b/.github/workflows/ragie-index.yml
new file mode 100644
index 0000000..493ca2a
--- /dev/null
+++ b/.github/workflows/ragie-index.yml
@@ -0,0 +1,151 @@
+name: Ragie Docs Sync
+
+on:
+ workflow_dispatch:
+ inputs:
+ partition:
+ description: 'Ragie partition to sync (e.g. shared_docs, tenant_acme)'
+ required: false
+ default: 'shared_docs'
+ mode:
+ description: 'Sync mode'
+ required: false
+ default: 'incremental'
+ type: choice
+ options:
+ - incremental
+ - full
+ doc_ref:
+ description: 'Optional single docs ref from docs.json'
+ required: false
+ default: ''
+ ensure_partition_context_aware:
+ description: 'Enable partition context-aware config'
+ required: false
+ default: 'true'
+ ensure_entity_instruction:
+ description: 'Ensure partition-scoped entity extraction instruction (no consumer yet; enable when retrieval uses entities)'
+ required: false
+ default: 'false'
+
+jobs:
+ ragie-sync:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+
+ - name: Validate RAGIE_API_KEY is configured
+ env:
+ RAGIE_API_KEY: ${{ secrets.RAGIE_API_KEY }}
+ run: |
+ if [ -z "$RAGIE_API_KEY" ]; then
+ echo "::error::Missing required secret RAGIE_API_KEY"
+ exit 1
+ fi
+
+ - name: Sync docs to Ragie
+ env:
+ RAGIE_API_KEY: ${{ secrets.RAGIE_API_KEY }}
+ GITHUB_SHA: ${{ github.sha }}
+ run: |
+ set -euo pipefail
+
+ PARTITION='${{ github.event.inputs.partition }}'
+ MODE='${{ github.event.inputs.mode }}'
+ DOC_REF='${{ github.event.inputs.doc_ref }}'
+ ENSURE_PARTITION_CONTEXT_AWARE='${{ github.event.inputs.ensure_partition_context_aware }}'
+ ENSURE_ENTITY_INSTRUCTION='${{ github.event.inputs.ensure_entity_instruction }}'
+
+ if [ -z "$PARTITION" ]; then
+ PARTITION='${{ vars.RAGIE_PARTITION }}'
+ fi
+ if [ -z "$PARTITION" ]; then
+ PARTITION='shared_docs'
+ fi
+ if [ -z "$MODE" ]; then
+ MODE='incremental'
+ fi
+ if [ -z "$ENSURE_PARTITION_CONTEXT_AWARE" ]; then
+ ENSURE_PARTITION_CONTEXT_AWARE='${{ vars.RAGIE_ENSURE_PARTITION_CONTEXT_AWARE }}'
+ fi
+ if [ -z "$ENSURE_ENTITY_INSTRUCTION" ]; then
+ ENSURE_ENTITY_INSTRUCTION='${{ vars.RAGIE_ENSURE_ENTITY_INSTRUCTION }}'
+ fi
+ if [ -z "$ENSURE_PARTITION_CONTEXT_AWARE" ]; then
+ ENSURE_PARTITION_CONTEXT_AWARE='true'
+ fi
+ if [ -z "$ENSURE_ENTITY_INSTRUCTION" ]; then
+ ENSURE_ENTITY_INSTRUCTION='false'
+ fi
+
+ ARGS=(--partition "$PARTITION" --mode "$MODE" --commit-sha "$GITHUB_SHA")
+ if [ -n "$DOC_REF" ]; then
+ ARGS+=(--doc-ref "$DOC_REF")
+ fi
+ case "${ENSURE_PARTITION_CONTEXT_AWARE,,}" in
+ 1|true|yes|y|on) ARGS+=(--ensure-partition-context-aware) ;;
+ esac
+ case "${ENSURE_ENTITY_INSTRUCTION,,}" in
+ 1|true|yes|y|on) ARGS+=(--ensure-entity-instruction) ;;
+ esac
+
+ python3 scripts/ragie_sync.py "${ARGS[@]}"
+
+ - name: Sync changed tenant partitions
+ if: github.event_name == 'push'
+ env:
+ RAGIE_API_KEY: ${{ secrets.RAGIE_API_KEY }}
+ GITHUB_SHA: ${{ github.sha }}
+ GITHUB_BEFORE: ${{ github.event.before }}
+ run: |
+ set -euo pipefail
+
+ BEFORE="${GITHUB_BEFORE:-}"
+ AFTER="${GITHUB_SHA}"
+
+ if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then
+ CHANGED="$(git ls-files 'tenants/*.md' 'tenants/*.mdx' 'tenants/**/*.md' 'tenants/**/*.mdx' || true)"
+ else
+ CHANGED="$(git diff --name-only "$BEFORE" "$AFTER" -- 'tenants/*.md' 'tenants/*.mdx' 'tenants/**/*.md' 'tenants/**/*.mdx' || true)"
+ fi
+
+ TENANTS="$(
+ printf '%s\n' "$CHANGED" |
+ awk -F/ '
+ /^tenants\// {
+ if (NF >= 3) {
+ print tolower($2)
+ } else if (NF == 2) {
+ base=$2
+ sub(/\.[^.]+$/, "", base)
+ base=tolower(base)
+ if (base != "readme" && base != "review") print base
+ }
+ }
+ ' |
+ grep -E '^[a-z0-9_-]+$' |
+ sort -u || true
+ )"
+
+ if [ -z "$TENANTS" ]; then
+ echo "No tenant docs changed; skipping tenant partition sync."
+ exit 0
+ fi
+
+ for TENANT in $TENANTS; do
+ PARTITION="tenant_${TENANT}"
+ echo "Syncing tenant partition ${PARTITION}"
+ python3 scripts/ragie_sync.py \
+ --partition "$PARTITION" \
+ --mode incremental \
+ --commit-sha "$GITHUB_SHA" \
+ --ensure-partition-context-aware
+ done
diff --git a/.gitignore b/.gitignore
index e5813f1..0589309 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,8 @@ node_modules
package-lock.json
package.json
desktop.ini
+.env
+
+# Nested repos (sibling projects)
+/reporting_queries/
+/uni/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..9713514
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "skills"]
+ path = skills
+ url = git@github.com:source-medium/skills.git
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..a891bea
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,251 @@
+# AGENT.md (Codex CLI)
+
+This file provides guidance to Codex CLI when working with the SourceMedium documentation repository.
+
+## Repository Overview
+
+This is a **Mintlify (MDX) documentation site** for SourceMedium, a data analytics platform for e-commerce brands.
+
+Key content areas:
+- `onboarding/` (getting started, analytics tooling)
+- `data-inputs/` (integrations + configuration sheet docs)
+- `data-transformations/` (naming conventions, transformation philosophy)
+- `data-activation/` (Managed Data Warehouse, Managed BI modules, data tables)
+- `help-center/` (FAQs, core concepts)
+- `mta/` (multi-touch attribution)
+
+Primary config:
+- `docs.json` (Mintlify navigation + site config)
+
+## Working Style (Codex-specific)
+
+- Prefer **deterministic** checks over guesswork. If you can’t prove a claim from repo sources, soften language or ask for clarification.
+- When asked for **audit/feedback only**, do not edit files. When asked to implement, keep diffs minimal and scoped.
+- Avoid inventing field names: for table/column accuracy, treat the **dbt codebase + MDW config** as source of truth.
+- Do not commit/push unless explicitly asked. When asked, run validations first.
+
+## Essential Commands
+
+```bash
+# Local preview (requires Mintlify CLI installed)
+mintlify dev
+
+# Basic validation
+python3 -m json.tool docs.json
+
+# Find Notion URLs (should be none in published docs)
+rg -n "notion\\.so|www\\.notion\\.so|notion\\.site" -S .
+```
+
+### Navigation reference validation (docs.json -> files exist)
+
+```bash
+python3 << 'PY'
+import json, os, sys
+def extract_refs(obj, refs):
+ if isinstance(obj, str) and not obj.startswith("http"):
+ refs.append(obj)
+ elif isinstance(obj, list):
+ for i in obj: extract_refs(i, refs)
+ elif isinstance(obj, dict):
+ for k, v in obj.items():
+ if k in ("tabs","pages","navigation","groups"):
+ extract_refs(v, refs)
+ return refs
+refs = extract_refs(json.load(open("docs.json")), [])
+missing = [f"{r}.mdx" for r in refs if not os.path.exists(f"{r}.mdx")]
+if missing:
+ print("Missing (first 10):", missing[:10])
+ sys.exit(1)
+print(f"OK: {len(refs)} nav refs resolve")
+PY
+```
+
+## Content Conventions
+
+- Filenames: kebab-case, `.mdx`.
+- Frontmatter is required for `.mdx`:
+ ```yaml
+ ---
+ title: "Page Title"
+ description: "Short SEO summary"
+ # optional: sidebarTitle, icon, route
+ ---
+ ```
+- Internal links: use site routes like `/data-activation/...` (no `.mdx`).
+- Directory links: use explicit `/folder/index` paths (Mintlify doesn't auto-resolve `/folder` to `/folder/index.mdx`).
+
+### Mintlify MDX components
+
+Use Mintlify components for consistent formatting:
+```mdx
+Informational note
+Helpful suggestion
+Important callout
+Caution or gotcha
+```
+
+## CI/CD checks (what PRs may fail on)
+
+Workflows validate:
+- JSON validity (`docs.json`)
+- spelling (codespell)
+- link checking (lychee)
+- navigation references resolve to files
+
+If spellcheck flags domain terms, add them to the workflow ignore list (don’t “misspell” product names).
+
+## Notion Policy
+
+- Do not leave Notion pages “floating around” as canonical docs.
+- Remove/replace links to Notion URLs (`notion.so`, `notion.site`) in published content.
+- When migrating content from Notion, convert to `.mdx`, add frontmatter, and ensure the page is reachable via `docs.json`.
+
+## Data Table Documentation (`sm_transformed_v2`)
+
+Table docs live in:
+- `data-activation/data-tables/sm_transformed_v2/*.mdx`
+
+These pages include a fenced YAML block that should mirror customer-facing schema.
+
+### Customer-facing dataset
+
+- Prefer examples using `your_project.sm_transformed_v2.
` (customer-facing).
+- Avoid legacy/internal dataset names like `masterset` in examples.
+
+### Source of truth for column names
+
+In the **monorepo** (common in this workspace), the dbt project lives adjacent to this docs repo.
+Use it to verify schema accuracy:
+- `../dbt_project.yml`
+- `../models/**`
+
+Key config:
+- Rename map: `vars.mdw_schema_config.rename_column_map_all`
+- Exclusions: `vars.mdw_schema_config.excluded_columns_all_tables`
+
+Interpretation:
+- Docs should reflect **post-rename** (customer-facing) column names.
+- Do not document excluded columns (even if they exist in dbt YAML).
+
+If the dbt codebase is not available, fall back to:
+- `yaml-files/latest-v2-schemas-*.json`
+- Warehouse inspection (`bq show --schema ...`) when available
+
+### Struct field documentation
+
+For struct/nested columns, document subfields with dot-notation when they are queryable as separate fields:
+```yaml
+- name: ad_platform_reported_conversion_windows
+ description: Struct containing conversion metrics across windows.
+
+- name: ad_platform_reported_conversion_windows.default_window
+ description: Platform default conversions window.
+```
+
+### Common pitfalls (high frequency)
+
+- Documenting excluded columns (e.g., columns listed in `excluded_columns_all_tables`)
+- Documenting pre-rename names (e.g., `smcid` instead of `sm_store_id`)
+- Directory links without `/index` suffix (use `/folder/index`, not `/folder`)
+- dbt YAML includes columns that may not be present in exported MDW schema (verify against config + warehouse when possible)
+- **Config vs production mismatch**: `dbt_project.yml` may show display labels (e.g., `'1st Order'`) but actual data uses different values (e.g., `'1st_order'`). Always verify enum values by querying `sm-democo.sm_transformed_v2.*` (see CLAUDE.md for SQL examples).
+
+## Navigation Restructure Guidelines
+
+When reorganizing `docs.json` navigation:
+
+### Safe Approach: Nav-Only Refactor
+1. **Change only `docs.json`** - Don't move files in the first pass
+2. **Run validation after every change** - `python3 -m json.tool docs.json` + nav ref check
+3. **Audit for orphan pages** - Compare files on disk vs pages in navigation
+
+### Orphan Page Detection
+After restructuring, verify no pages were dropped:
+```bash
+# Find .mdx files not in docs.json (potential orphans)
+comm -23 <(find . -name "*.mdx" -not -path "./snippets/*" | sed 's|^\./||;s|\.mdx$||' | sort) \
+ <(python3 -c "import json; exec('''
+def extract(obj, refs):
+ if isinstance(obj, str) and not obj.startswith(\"http\"): refs.append(obj)
+ elif isinstance(obj, list): [extract(i, refs) for i in obj]
+ elif isinstance(obj, dict): [extract(v, refs) for k,v in obj.items() if k in (\"tabs\",\"pages\",\"navigation\",\"groups\")]
+ return refs
+print(\"\\n\".join(sorted(extract(json.load(open(\"docs.json\")), []))))
+''')" | sort)
+```
+
+### URL Verification
+**Never hallucinate URLs** - Always derive URLs from actual file paths:
+- File: `help-center/faq/data-faqs/why-dont-new-customers-match.mdx`
+- URL: `https://docs.sourcemedium.com/help-center/faq/data-faqs/why-dont-new-customers-match`
+
+The validation script checks file existence, NOT URL correctness. When opening pages for QA, copy paths from `docs.json` or file listings.
+
+### Recommended deterministic audit (monorepo)
+
+If `../dbt_project.yml` exists, compare docs table YAML blocks against dbt YAML columns,
+applying `rename_column_map_all` and excluding `excluded_columns_all_tables`.
+(Keep this check as a gate for "schema accuracy" work.)
+
+### Handling Orphaned Files During Consolidation
+
+When consolidating docs, don't delete old files immediately:
+1. Add redirect `` notice pointing to new location
+2. Keep in place for one release cycle (allows external links to still work)
+3. Delete in follow-up PR after confirming no broken external references
+
+Example redirect notice:
+```mdx
+
+This page has moved to [New Location](/path/to/new-page). Please update your bookmarks.
+
+```
+
+## SQL Examples in Documentation
+
+### Validation Requirement
+**All SQL examples MUST be validated by an engineer before merging.** Run queries against a test warehouse (e.g., `sm-democo`) using BigQuery dry-run to catch syntax and schema errors:
+
+```bash
+bq query --dry_run --use_legacy_sql=false "SELECT ... FROM \`sm-democo.sm_transformed_v2.obt_orders\` ..."
+```
+
+### Query Standards
+1. **Required filters for order tables:**
+ ```sql
+ WHERE is_order_sm_valid = TRUE
+ ```
+
+2. **Dataset paths:** Use placeholder format for customer docs:
+ ```sql
+ FROM `your_project.sm_transformed_v2.obt_orders` -- Standard tables
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models` -- MTA tables
+ ```
+
+3. **Placeholders:** Use `your_project` and `your-sm_store_id` consistently (not `{{account_id}}` or `smcid`)
+
+4. **Safe division:** Always use `SAFE_DIVIDE()` to avoid division-by-zero errors
+
+5. **Date/timestamp handling:** BigQuery is strict about types:
+ ```sql
+ -- Correct: wrap timestamp in DATE() when comparing to DATE
+ WHERE DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+
+ -- Wrong: comparing TIMESTAMP to DATE directly
+ WHERE order_processed_at_local_datetime >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ ```
+
+### Common Pitfalls
+- **Column `smcid` doesn't exist** → Use `sm_store_id`
+- **Column `sm_marketing_channel` doesn't exist** → Use `sm_channel`
+- **Reserved word `rows`** → Use `row_count` or another alias
+- **Missing required filters** → Order queries need `is_order_sm_valid = TRUE`
+
+## When you're unsure
+
+- Prefer asking a targeted question over writing speculative content.
+- For external platform defaults/claims (Meta/Google/TikTok attribution windows, etc.), only state specifics if:
+ - they're documented in-repo, or
+ - you add explicit caveats ("varies by account settings; confirm in platform UI").
+
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..dc94860
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,385 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code when working with the SourceMedium documentation repository.
+
+## Project Overview
+
+This is a **Mintlify documentation site** for SourceMedium, a data analytics platform for e-commerce brands. The docs cover:
+- Platform integrations (Shopify, Meta, Google Ads, Klaviyo, etc.)
+- Data transformation and activation
+- Dashboard/BI usage guides
+- Attribution and analytics concepts
+
+**Tech Stack:** Mintlify (MDX-based docs framework), GitHub Actions for CI/CD
+
+## Essential Commands
+
+```bash
+# Local development
+mintlify dev # Start local dev server (requires npm install -g mintlify)
+
+# Validation (run before committing)
+python3 -m json.tool docs.json # Validate JSON syntax
+
+# Navigation validation script (from CI workflow)
+python3 << 'EOF'
+import json, os, sys
+def extract_refs(obj, refs=[]):
+ if isinstance(obj, str) and not obj.startswith('http'): refs.append(obj)
+ elif isinstance(obj, list): [extract_refs(i, refs) for i in obj]
+ elif isinstance(obj, dict): [extract_refs(v, refs) for k,v in obj.items() if k in ('tabs','pages','navigation','groups')]
+ return refs
+refs = extract_refs(json.load(open('docs.json')))
+missing = [f"{r}.mdx" for r in refs if not os.path.exists(f"{r}.mdx")]
+if missing: print(f"Missing: {missing[:10]}"); sys.exit(1)
+print(f"✅ All {len(refs)} nav refs valid")
+EOF
+```
+
+## Directory Structure
+
+```
+sourcemedium-docs/
+├── docs.json # Main navigation config (Mintlify)
+├── help-center/ # FAQs, guides, troubleshooting
+│ ├── faq/
+│ │ ├── account-management-faqs/
+│ │ ├── dashboard-functionality-faqs/
+│ │ ├── data-faqs/
+│ │ └── configuration-sheet-faqs/
+│ └── core-concepts/
+├── data-inputs/ # Integration guides
+│ ├── platform-integration-instructions/ # Setup guides per platform
+│ ├── platform-supporting-resources/ # Platform-specific deep dives
+│ ├── configuration-sheet/ # Config sheet docs
+│ └── attribution-health/ # Attribution improvement guides
+├── data-transformations/ # How SM transforms data
+│ └── naming-conventions/ # Column/table naming standards
+├── data-activation/ # Using SM data
+│ ├── managed-data-warehouse/
+│ ├── managed-bi-v1/modules/
+│ ├── data-tables/ # Table documentation
+│ └── template-resources/ # Looker Studio templates
+├── onboarding/ # Getting started content
+│ ├── getting-started/
+│ └── analytics-tools/
+├── mta/ # Multi-Touch Attribution docs
+├── snippets/ # Reusable MDX snippets
+├── images/ # All images (article-imgs/, platform-logos/)
+└── .github/workflows/ # CI/CD (docs-quality.yml)
+```
+
+## docs.json Navigation Structure
+
+The navigation uses a `tabs > groups > pages` hierarchy:
+
+```json
+{
+ "navigation": {
+ "tabs": [
+ {
+ "tab": "Tab Name",
+ "groups": [
+ {
+ "group": "Group Name",
+ "pages": [
+ "path/to/page", // Simple page reference
+ { // Nested group
+ "group": "Nested Group",
+ "pages": ["path/to/nested-page"]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
+```
+
+**Current Tabs:**
+- Overview (getting started, core concepts)
+- Connect Your Data (integrations, configuration)
+- Understand Your Data (transformations, attribution)
+- Use Your Data (MDW, dashboards, data tables)
+- Reference (metrics, dimensions, data dictionary)
+- Help (FAQs, troubleshooting)
+- MTA (multi-touch attribution)
+
+**Important:** Page references are paths WITHOUT `.mdx` extension. They must match actual file paths.
+
+## MDX Components
+
+Mintlify provides these components (use them for consistent formatting):
+
+### Callouts
+```mdx
+Informational note
+Helpful suggestion
+Important callout
+Caution or gotcha
+```
+
+### Cards & Groups
+```mdx
+
+
+ Card description
+
+
+```
+
+### Tabs
+```mdx
+
+ Content for first tab
+ Content for second tab
+
+```
+
+### Accordions
+```mdx
+
+ Hidden content revealed on click
+
+
+
+ Content 1
+ Content 2
+
+```
+
+### Steps
+```mdx
+
+ First step content
+ Second step content
+
+```
+
+### Tooltips & Snippets
+```mdx
+Term
+
+{/* Include reusable snippet */}
+
+```
+
+## Frontmatter
+
+Every `.mdx` file needs frontmatter:
+
+```yaml
+---
+title: "Page Title" # Required
+sidebarTitle: "Short Nav Title" # Optional - shorter title for sidebar
+description: "SEO description" # Optional but recommended
+icon: 'icon-name' # Optional - Font Awesome icon
+---
+```
+
+Common icons: `plug`, `chart-line`, `question-mark`, `book`, `gear`, `heart-pulse`, `tags`
+
+## CI/CD Quality Checks
+
+PRs trigger `.github/workflows/mintlify-docs-update.yml` which validates:
+
+1. **JSON Validation** - Ensures docs.json is valid
+2. **Navigation Validation** - All page refs point to existing files
+3. **Mintlify Validation** - Runs `mintlify validate` (non-blocking due to pre-existing MDX issues)
+
+**Note:** Mintlify auto-deploys on merge to master. The CI workflow is validation-only—no build/deploy steps needed.
+
+**Ignored terms** (add to workflow if needed): smcid, sourcemedium, hdyhau, utm, cogs, ltv, roas, aov, klaviyo, shopify, etc.
+
+## Writing Guidelines
+
+### Terminology
+- **SMCID** - SourceMedium Customer ID (unique identifier)
+- **HDYHAU** - "How Did You Hear About Us?" (post-purchase survey)
+- **MTA** - Multi-Touch Attribution
+- **LTV** - Lifetime Value
+- **ROAS** - Return on Ad Spend
+- **AOV** - Average Order Value
+- **Zero-party data** - Customer-provided info (surveys)
+- **First-party data** - Tracking-based data (UTMs, GA4)
+
+### Style
+- Use sentence case for headings
+- Prefer active voice
+- Keep paragraphs short (3-4 sentences max)
+- Use tables for comparisons and reference info
+- Use CardGroups for related links/resources
+- Use Tabs for alternative approaches or platform-specific content
+
+### Links
+- **Internal:** Use relative paths `/data-inputs/platform-integration-instructions/shopify-integration`
+- **External:** Full URLs `https://example.com`
+- **Never:** Use old `help.sourcemedium.com` URLs (these are deprecated)
+
+## Common Tasks
+
+### Adding a new integration guide
+1. Create file: `data-inputs/platform-integration-instructions/-integration.mdx`
+2. Add to `docs.json` navigation under appropriate group
+3. Optionally create supporting resources in `data-inputs/platform-supporting-resources//`
+
+### Adding a new FAQ
+1. Create file in appropriate `help-center/faq//` folder
+2. Add to `docs.json` under "Help" tab > appropriate FAQ group
+
+### Restructuring Navigation
+When reorganizing `docs.json`:
+1. **Nav-only first** - Change docs.json without moving files
+2. **Validate after each change** - Run JSON + nav ref validation
+3. **Check for orphans** - See AGENT.md for orphan detection script
+4. **Single location per page** - Each page should appear in exactly one place in nav
+
+### Adding images
+1. Place in `images/article-imgs/` (or `platform-logos/` for logos)
+2. Reference as `/images/article-imgs/filename.png`
+
+### Creating reusable content
+1. Create snippet in `snippets/snippet-name.mdx`
+2. Use with ``
+
+## Data Table Documentation (sm_transformed_v2)
+
+The `data-activation/data-tables/sm_transformed_v2/` folder contains schema docs for customer-facing tables. These require special attention to ensure accuracy.
+
+### Customer-Facing Dataset
+- **Correct:** `sm_transformed_v2` - This is the dataset customers query
+- **Incorrect:** `masterset` - Legacy internal dataset, NOT customer-facing
+- All SQL examples in docs should use `your_project.sm_transformed_v2.
`
+
+### MDW Column Exclusions
+The Managed Data Warehouse (MDW) automatically excludes certain columns. **Never document these in table docs:**
+
+1. **Explicit exclusions** - Listed in `dbt_project.yml` under `vars.mdw.excluded_columns_all_tables`:
+ - `sm_order_referrer_source`, `_synced_at`, etc.
+
+2. **Naming convention exclusions** (from MDW macros):
+ - Columns ending in `_array` (e.g., `order_tags_array`)
+ - Columns starting with `_` (e.g., `_synced_at`)
+
+3. **Column renames** - Check `vars.mdw.rename_column_map_all` for transformed names
+
+### Verifying Against Real Warehouse
+Before publishing table docs, verify columns exist in customer MDW:
+
+```bash
+# Check actual schema in a customer warehouse
+bq show --schema sm-irestore4:sm_transformed_v2. | jq -r '.[].name' | sort
+
+# Compare with documented columns
+grep "name:"
.mdx | sed 's/.*name: //' | sort
+
+# Find differences
+comm -23 <(documented) <(actual) # In docs but not warehouse
+```
+
+### Struct Field Documentation
+For struct/nested columns, document subfields with dot notation:
+```yaml
+- name: ad_platform_reported_conversion_windows
+ description: Struct containing conversion metrics...
+
+- name: ad_platform_reported_conversion_windows.default_window
+ description: Platform-reported conversions using default window...
+
+- name: ad_platform_reported_conversion_windows._7d_click
+ description: Platform-reported conversions using 7-day click window...
+```
+
+### Common Pitfalls
+- **dbt YAML ≠ MDW schema** - Columns can be documented in dbt but not implemented in SQL
+- **Array columns** - Always excluded from MDW, never document them
+- **Duplicate entries** - Watch for accidentally documenting same column twice
+- **Directory links** - Use `/folder/index` explicitly (Mintlify doesn't auto-resolve `/folder` to `/folder/index.mdx`)
+
+### Verifying Enum Values
+**CRITICAL:** Config files (`dbt_project.yml`) may show display labels that differ from actual data values. Always verify enum values against production data:
+
+```sql
+-- Verify actual values in sm-democo warehouse
+SELECT DISTINCT order_sequence FROM `sm-democo.sm_transformed_v2.obt_orders` WHERE order_sequence IS NOT NULL
+-- Returns: 1st_order, repeat_order (NOT 'First Order', 'Repeat Order')
+
+SELECT DISTINCT subscription_order_sequence FROM `sm-democo.sm_transformed_v2.obt_orders` WHERE subscription_order_sequence IS NOT NULL
+-- Returns: 1st_sub_order, recurring_sub_order, one_time_order
+```
+
+**Pattern:** Config files describe intended display values; actual implementation uses snake_case constants. Query production data, not config files.
+
+## SQL Examples in Documentation
+
+### Validation Requirement
+**All SQL examples MUST be validated by an engineer before merging.** Run queries against a test warehouse (e.g., `sm-democo`) using BigQuery dry-run to catch syntax and schema errors:
+
+```bash
+bq query --dry_run --use_legacy_sql=false "SELECT ... FROM \`sm-democo.sm_transformed_v2.obt_orders\` ..."
+```
+
+### Query Standards
+1. **Required filters for order tables:**
+ ```sql
+ WHERE is_order_sm_valid = TRUE
+ ```
+
+2. **Dataset paths:** Use placeholder format for customer docs:
+ ```sql
+ FROM `your_project.sm_transformed_v2.obt_orders` -- Standard tables
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models` -- MTA tables
+ ```
+
+3. **Placeholders:** Use `your_project` and `your-sm_store_id` consistently (not `{{account_id}}` or `smcid`)
+
+4. **Safe division:** Always use `SAFE_DIVIDE()` to avoid division-by-zero errors
+
+5. **Date/timestamp handling:** BigQuery is strict about types:
+ ```sql
+ -- Correct: wrap timestamp in DATE() when comparing to DATE
+ WHERE DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+
+ -- Wrong: comparing TIMESTAMP to DATE directly
+ WHERE order_processed_at_local_datetime >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ ```
+
+### Common Pitfalls
+- **Column `smcid` doesn't exist** → Use `sm_store_id`
+- **Column `sm_marketing_channel` doesn't exist** → Use `sm_channel`
+- **Reserved word `rows`** → Use `row_count` or another alias
+- **Missing required filters** → Order queries need `is_order_sm_valid = TRUE`
+
+## Pre-Commit Validation
+
+Run the validation commands from [Essential Commands](#essential-commands), plus:
+
+```bash
+# Test external URLs (spot check key links)
+curl -sI "https://support.google.com/looker-studio/" | head -1
+# Should return HTTP/2 200
+```
+
+### Handling Orphaned Files
+When consolidating docs, don't delete old files immediately. Instead:
+1. Add redirect `` notice pointing to new location
+2. Keep in place for one release cycle (allows external links to still work)
+3. Delete in follow-up PR after confirming no broken external references
+
+## Troubleshooting
+
+### "Page not found" in local dev
+- Check file path matches docs.json reference exactly
+- Ensure `.mdx` extension exists on file but NOT in docs.json
+
+### CI failing on spell check
+- Add legitimate terms to `ignore_words_list` in `.github/workflows/docs-quality.yml`
+
+### CI failing on link check
+- Fix broken internal links (check file exists)
+- For flaky external links, add to `--exclude` in lychee args
+
+### Navigation not updating
+- Ensure valid JSON in docs.json (run `python3 -m json.tool docs.json`)
+- Check page path exists as `.mdx` file
diff --git a/README.md b/README.md
index dec9a5e..c5458a1 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,31 @@ This repository contains the Mintlify documentation for the Source Medium dbt re
## Documentation Workflows
-### Automatic Documentation Generation
+### Updating Docs from Parent Repository
-Documentation is automatically generated from the dbt repository using a custom script that:
+Documentation can be updated from the parent dbt repository (`reporting_queries`) using the following steps:
-1. Extracts information from dbt's manifest and catalog files
-2. Converts it to Markdown files in the appropriate directories
-3. Commits and pushes changes to this repository
+1. Navigate to the parent repository root:
+ ```bash
+ cd /path/to/reporting_queries
+ ```
+
+2. Run the documentation generation script:
+ ```bash
+ ./bin/generate_mintlify_docs.sh
+ ```
+
+3. The script will:
+ - Extract information from dbt's manifest and catalog files
+ - Convert it to Markdown files in the appropriate directories
+ - Commit and push changes to this repository
+
+4. After the script finishes, update the submodule reference in the parent repository:
+ ```bash
+ git add mintlify
+ git commit -m "Update mintlify docs"
+ git push
+ ```
### Direct Documentation Editing
@@ -23,26 +41,32 @@ For making direct changes to documentation files (not generated from dbt), follo
2. Make your changes to the documentation files
-3. Commit and push your changes:
+3. Preview your changes locally (requires Mintlify CLI):
+ ```bash
+ npm i -g mintlify # Install if not already installed
+ mintlify dev
+ ```
+
+4. Commit and push your changes:
```bash
git add .
git commit -m "Description of your changes"
git push -u origin your-branch-name
```
-4. Create a pull request using GitHub CLI:
+5. Create a pull request using GitHub CLI:
```bash
gh pr create --title "Your PR title" --body "Description of your changes"
```
-5. Merge the pull request:
+6. Merge the pull request:
```bash
gh pr merge --merge
```
-6. After merging, don't forget to update the main repository to point to the latest version of this submodule.
+7. After merging, don't forget to update the main repository to point to the latest version of this submodule.
-7. When sending Slack notifications about documentation updates, include a link to the PR diffs:
+8. When sending Slack notifications about documentation updates, include a link to the PR diffs:
```
📚 *Documentation Update*:
@@ -52,7 +76,7 @@ For making direct changes to documentation files (not generated from dbt), follo
```
This allows team members to easily view the changes made to the documentation.
-## File Structure
+## Content Structure
- `models/`: Documentation for dbt models
- `macros/`: Documentation for dbt macros
@@ -63,9 +87,34 @@ For making direct changes to documentation files (not generated from dbt), follo
- `data-transformations/`: Documentation for data transformation processes
- `data-activation/`: Documentation for data activation platforms
+## Adding New Content
+
+Add new content with MDX files using this template:
+
+```md
+---
+title: "Page Title"
+sidebarTitle: "Sidebar title (optional - if different from page title)"
+description: "Subtitle (optional)"
+---
+
+Content goes here...
+```
+
+## Customizing Branding
+
+Brand settings are configured in `docs.json`, including:
+- Company name
+- Logo
+- Favicon
+- Color scheme
+- Navigation structure
+
## Deployment
-Documentation is automatically deployed to the Mintlify site when changes are pushed to the main branch of this repository.
+Documentation is automatically deployed to the Mintlify site when changes are pushed to the master branch of this repository via the GitHub workflow in `.github/workflows/mintlify-docs-update.yml`.
+
+If the GitHub workflow fails, you can manually deploy through the Mintlify dashboard.
## Documentation URL
@@ -73,4 +122,4 @@ Our documentation is available at: https://docs.sourcemedium.com/
## Last Updated
-This documentation was last tested on: `March 4, 2024 at 3:00 PM PST`
+This documentation was last tested on: `March 5, 2024`
diff --git a/advanced-insights-and-strategy/case-studies/case-studies-placeholder.mdx b/advanced-insights-and-strategy/case-studies/case-studies-placeholder.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/advanced-insights-and-strategy/insights-overview.mdx b/advanced-insights-and-strategy/insights-overview.mdx
deleted file mode 100644
index 1a300c0..0000000
--- a/advanced-insights-and-strategy/insights-overview.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Insights & Strategy'
-description: 'Making data actionable'
-icon: 'star'
----
\ No newline at end of file
diff --git a/ai-analyst/agent-skills/bigquery-access-request-template.mdx b/ai-analyst/agent-skills/bigquery-access-request-template.mdx
new file mode 100644
index 0000000..3ed3923
--- /dev/null
+++ b/ai-analyst/agent-skills/bigquery-access-request-template.mdx
@@ -0,0 +1,83 @@
+---
+title: "BigQuery Access Request Template"
+sidebarTitle: "Access Request Template"
+description: "Copy/paste template and minimum IAM roles to request BigQuery access"
+icon: "key"
+---
+
+If you can’t run queries yet, use this page to request the exact access your internal Google Cloud admin should grant.
+
+## Minimum required roles
+
+For a read-only analyst workflow, request:
+
+1. **Project-level role**
+ - `roles/bigquery.jobUser`
+2. **Dataset-level roles**
+ - `roles/bigquery.dataViewer` on `sm_transformed_v2`
+ - `roles/bigquery.dataViewer` on `sm_metadata`
+
+Optional:
+
+1. `roles/bigquery.dataViewer` on `sm_experimental` (if querying MTA/experimental tables)
+2. `roles/bigquery.dataViewer` on any custom tenant datasets you need
+
+
+`roles/bigquery.jobUser` lets users create query jobs. `roles/bigquery.dataViewer` lets users read/query dataset data.
+
+
+## Copy/paste message to send your admin
+
+```text
+Subject: BigQuery access request for SourceMedium analysis
+
+Hi Admin Team,
+
+Please grant BigQuery access for:
+- Principal:
+- Project:
+
+Required permissions:
+1) Project-level role:
+ - roles/bigquery.jobUser
+
+2) Dataset-level roles:
+ - roles/bigquery.dataViewer on .sm_transformed_v2
+ - roles/bigquery.dataViewer on .sm_metadata
+
+Optional (if needed for MTA/experimental analysis):
+- roles/bigquery.dataViewer on .sm_experimental
+
+Success criteria after grant:
+- `bq query --use_legacy_sql=false --dry_run 'SELECT 1 AS ok'` succeeds
+- `bq query --use_legacy_sql=false "SELECT 1 FROM \`.sm_transformed_v2.obt_orders\` LIMIT 1"` succeeds
+
+Thanks.
+```
+
+## How admins grant this access
+
+1. Project role (`bigquery.jobUser`):
+ - Go to IAM for the project and grant the role to the user/group.
+2. Dataset roles (`bigquery.dataViewer`):
+ - In BigQuery, open dataset sharing/permissions and grant role on each required dataset.
+
+## Official references
+
+1. BigQuery IAM roles:
+ - https://cloud.google.com/bigquery/docs/access-control
+2. Dataset/table/view IAM in BigQuery:
+ - https://cloud.google.com/bigquery/docs/control-access-to-resources-iam
+3. Project IAM role management:
+ - https://cloud.google.com/iam/docs/granting-changing-revoking-access
+
+## Related pages
+
+
+
+ Skill overview and install path.
+
+
+ First queries and SourceMedium table usage.
+
+
diff --git a/ai-analyst/agent-skills/index.mdx b/ai-analyst/agent-skills/index.mdx
new file mode 100644
index 0000000..b41baad
--- /dev/null
+++ b/ai-analyst/agent-skills/index.mdx
@@ -0,0 +1,80 @@
+---
+title: "Agent Skills"
+sidebarTitle: "Agent Skills"
+description: "Installable skills for coding agents that work with SourceMedium data"
+icon: "wand-magic-sparkles"
+---
+
+Agent Skills package repeatable workflows that help coding agents assist with SourceMedium data analysis.
+
+## Quick Start (Copy/Paste)
+
+Give this prompt to your coding agent to install everything automatically:
+
+
+Copy the block below and paste it into Claude Code, Cursor, Windsurf, or any skills-compatible agent.
+
+
+```
+Install the SourceMedium BigQuery analyst skill and help me verify my setup:
+
+1. Run: npx skills add source-medium/skills --skill sm-bigquery-analyst
+2. Run the setup verification commands from the skill
+3. Confirm my BigQuery access is working
+
+My tenant ID is: [your-tenant-id]
+My project is: sm-[your-tenant-id]
+```
+
+---
+
+## Install
+
+```bash
+npx skills add source-medium/skills --skill sm-bigquery-analyst
+```
+
+The CLI detects your installed agents (Claude Code, Cursor, Windsurf, etc.) and installs to all of them.
+
+---
+
+## Available Skills
+
+
+
+ Query SourceMedium BigQuery safely with SQL receipts. SELECT-only, cost-guarded.
+
+
+
+---
+
+## After Installing
+
+Once installed, ask your coding agent questions like:
+
+```
+What was my revenue by channel last month?
+```
+
+```
+Show me new customer acquisition by source over the past 30 days
+```
+
+```
+What's my customer LTV by cohort?
+```
+
+Your agent will:
+1. Verify your BigQuery access
+2. Generate the correct SQL
+3. Return an auditable "SQL receipt" you can verify
+
+---
+
+## Related
+
+
+
+ Copy/paste request for internal admins when users do not have BigQuery access yet.
+
+
diff --git a/ai-analyst/agent-skills/sm-bigquery-analyst.mdx b/ai-analyst/agent-skills/sm-bigquery-analyst.mdx
new file mode 100644
index 0000000..7553cdd
--- /dev/null
+++ b/ai-analyst/agent-skills/sm-bigquery-analyst.mdx
@@ -0,0 +1,315 @@
+---
+title: "SM BigQuery Analyst"
+sidebarTitle: "SM BigQuery Analyst"
+description: "Query SourceMedium BigQuery safely with SQL receipts. SELECT-only, cost-guarded."
+icon: "database"
+---
+
+Query SourceMedium-hosted BigQuery data safely with auditable SQL receipts.
+
+## Quick Start (Copy/Paste)
+
+
+Copy the block below and paste it into your coding agent to install and verify setup automatically.
+
+
+```
+Install the SourceMedium BigQuery analyst skill:
+
+1. Run: npx skills add source-medium/skills --skill sm-bigquery-analyst
+2. Read the installed SKILL.md to understand the workflow
+3. Run the setup verification commands to check my BigQuery access
+
+My tenant ID is: [your-tenant-id]
+My project is: sm-[your-tenant-id]
+```
+
+---
+
+## Install
+
+```bash
+npx skills add source-medium/skills --skill sm-bigquery-analyst
+```
+
+Or copy the SKILL.md content below into your coding agent's skills folder.
+
+## What this skill does
+
+1. **Setup verification** — validates gcloud/bq CLI, authentication, and table access
+2. **Safe queries** — SELECT-only, dry-run first, cost-guarded
+3. **SQL receipts** — every answer includes copy/paste SQL + verification command
+4. **No fabrication** — if access fails, returns exact error and access request template
+
+---
+
+## Example Questions
+
+After installing, ask your coding agent:
+
+```
+What was my revenue by channel last month?
+```
+
+```
+Show me new customer acquisition by source over the past 30 days
+```
+
+```
+What's my customer LTV by acquisition cohort? Use sm_order_line_type = 'all_orders'
+```
+
+Your agent will verify access, generate SQL, and return an auditable receipt.
+
+---
+
+## SKILL.md
+
+Copy everything below into `.claude/skills/sm-bigquery-analyst/SKILL.md` (or equivalent for your agent):
+
+```markdown
+---
+name: sm-bigquery-analyst
+description: Query SourceMedium-hosted BigQuery safely. Emits SQL receipts. SELECT-only, cost-guarded. Use when users need help with BigQuery setup, access verification, or analytical questions against SourceMedium datasets.
+compatibility: Requires gcloud CLI, bq CLI, and network access to BigQuery.
+metadata:
+ author: sourcemedium
+ version: "1.0"
+---
+
+# SourceMedium BigQuery Analyst
+
+Use this skill to help end users work with SourceMedium BigQuery data from setup to analysis.
+
+## Workflow
+
+1. **Verify environment** (run these before any analysis)
+2. Confirm project and dataset/table visibility
+3. Use docs-first guidance for definitions and table discovery
+4. Answer analytical questions with reproducible SQL receipts
+5. Call out assumptions and caveats explicitly
+
+## Setup Verification
+
+Run these commands in order before writing analysis SQL:
+
+~~~bash
+# 1. Check CLI tools are installed
+gcloud --version && bq version
+
+# 2. Check authenticated account
+gcloud auth list
+
+# 3. Check active project
+gcloud config get-value project
+
+# 4. Validate BigQuery API access (dry-run)
+bq query --use_legacy_sql=false --dry_run 'SELECT 1 AS ok'
+
+# 5. Test table access (your project is named sm-)
+# Example: if your tenant is "acme-corp", your project is sm-acme-corp
+bq query --use_legacy_sql=false --dry_run "
+ SELECT 1
+ FROM \`sm-.sm_transformed_v2.obt_orders\`
+ LIMIT 1
+"
+
+# 6. Confirm you can actually read data (not just dry-run)
+bq query --use_legacy_sql=false "
+ SELECT 1
+ FROM \`sm-.sm_transformed_v2.obt_orders\`
+ WHERE is_order_sm_valid = TRUE
+ LIMIT 1
+"
+~~~
+
+If any step fails, direct the user to request access from their internal admin.
+
+## Safety Rules
+
+These are hard constraints. Do not bypass.
+
+### Query Safety
+
+1. **SELECT-only** — deny: INSERT, UPDATE, DELETE, MERGE, CREATE, DROP, EXPORT, COPY
+2. **Dry-run first** when iterating on new queries:
+ ~~~bash
+ bq query --use_legacy_sql=false --dry_run ''
+ ~~~
+3. **Enforce cost limit** with maximum bytes billed:
+ ~~~bash
+ bq query --use_legacy_sql=false --maximum_bytes_billed=1073741824 ''
+ ~~~
+ (1GB = 1073741824 bytes. If it fails due to bytes billed, tighten filters or ask for approval.)
+4. **Always bound queries**:
+ - Add `LIMIT` clause (max 100 rows for exploratory)
+ - Use date/partition filters when querying partitioned tables
+ - Prefer `WHERE` filters on partition columns
+
+### Data Safety
+
+1. **Default to aggregates** — avoid outputting raw rows unless explicitly requested
+2. **PII handling**:
+ - Do not output columns likely containing PII (email, phone, address, name) without explicit confirmation
+ - If PII is requested, confirm scope and purpose before proceeding
+ - Prefer anonymization. Example:
+ ~~~sql
+ -- Hash PII instead of exposing raw values
+ SELECT TO_HEX(SHA256(LOWER(email))) AS email_hash, ...
+ ~~~
+
+### Cost Guardrails
+
+~~~sql
+-- Good: bounded scan
+SELECT ... FROM `sm-.sm_transformed_v2.obt_orders`
+WHERE DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+LIMIT 100
+
+-- Bad: full table scan
+SELECT ... FROM `sm-.sm_transformed_v2.obt_orders` -- no filters
+~~~
+
+## Output Contract
+
+For analytical questions, always return:
+
+1. **Answer** — concise plain-English conclusion
+2. **SQL (copy/paste)** — BigQuery Standard SQL used for the result
+3. **Notes** — timeframe, metric definitions, grain, scope, timezone, attribution lens
+4. **Verify** — `bq query --use_legacy_sql=false --dry_run ''` command
+5. **Bytes scanned** — if >1GB, note this and ask for approval before running
+
+If access/setup fails, do not fabricate results. Return:
+
+1. Exact failing step
+2. Exact project/dataset that failed
+3. Direct user to the BigQuery access request template
+
+## Query Guardrails
+
+1. Fully qualify tables as `` `sm-.dataset.table` ``
+2. For order analyses, default to `WHERE is_order_sm_valid = TRUE`
+3. Use `sm_store_id` (not `smcid` — that name does not exist in customer tables)
+4. Use `SAFE_DIVIDE` for ratio math
+5. Handle DATE/TIMESTAMP typing explicitly (`DATE(ts_col)` when comparing to dates)
+6. Use `order_net_revenue` for revenue metrics (not `order_gross_revenue` unless explicitly asked)
+7. **Prefer `*_local_datetime` columns** when available for date-based reporting; otherwise be explicit about UTC vs local
+8. **For enumerations** (channel, platform, status), discover values with `SELECT DISTINCT` first, then use exact match. Reserve `LIKE`/`REGEXP` for free-text fields (`utm_campaign`, `product_title`, `page_path`)
+9. **LTV tables (`rpt_cohort_ltv_*`)**: always filter `sm_order_line_type` to exactly ONE value
+
+## Key Tables
+
+| Table | Grain | Use case |
+|-------|-------|----------|
+| `obt_orders` | 1 row per order | Revenue, profitability, channel analysis |
+| `obt_order_lines` | 1 row per line item | Product performance, margins, COGS |
+| `obt_customers` | 1 row per customer | Acquisition, retention, subscription status |
+| `rpt_ad_performance_daily` | 1 row per channel/date | Ad spend, impressions, clicks |
+| `rpt_cohort_ltv_*` | 1 row per cohort x month | LTV analysis (filter sm_order_line_type!) |
+
+## Project & Filtering
+
+**Project naming:** Customer projects are named `sm-`. Example: `sm-acme-corp`.
+
+**Multi-store filtering:** If you have multiple stores, filter by `sm_store_id` to analyze a single store. Without this filter, all stores' data is combined.
+
+**Sales channels:** Always filter or group by `sm_channel` for segmentation:
+- `online_dtc` — Direct-to-consumer website
+- `amazon` — Amazon marketplace
+- `tiktok_shop` — TikTok Shop
+
+## Example Queries
+
+### Daily revenue by channel
+
+~~~sql
+SELECT
+ DATE(order_processed_at_local_datetime) AS order_date,
+ sm_channel,
+ COUNT(sm_order_key) AS order_count,
+ SUM(order_net_revenue) AS revenue
+FROM `sm-.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+GROUP BY 1, 2
+ORDER BY 1 DESC
+~~~
+
+### New customer acquisition
+
+~~~sql
+SELECT
+ DATE(order_processed_at_local_datetime) AS order_date,
+ sm_utm_source_medium,
+ COUNT(DISTINCT sm_customer_key) AS new_customers,
+ SUM(order_net_revenue) AS revenue,
+ SAFE_DIVIDE(SUM(order_net_revenue), COUNT(DISTINCT sm_customer_key)) AS avg_first_order_value
+FROM `sm-.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_sequence = '1st_order'
+GROUP BY 1, 2
+ORDER BY 1 DESC
+~~~
+
+### LTV cohort (CRITICAL: filter sm_order_line_type)
+
+~~~sql
+SELECT
+ cohort_month,
+ months_since_first_order,
+ AVG(SAFE_DIVIDE(cumulative_order_net_revenue, cohort_size)) AS avg_ltv
+FROM `sm-.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+WHERE sm_order_line_type = 'all_orders'
+ AND acquisition_order_filter_dimension = 'source/medium'
+ AND months_since_first_order <= 12
+GROUP BY 1, 2
+ORDER BY 1, 2
+~~~
+
+### Discover available metrics
+
+Query `sm_metadata.dim_semantic_metric_catalog` to find 180+ pre-defined metrics:
+
+~~~sql
+-- Find all revenue metrics
+SELECT metric_name, metric_label, calculation
+FROM `sm-.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_category = 'revenue'
+ORDER BY metric_name
+
+-- Resolve abbreviated names (aov, mer, cac, roas)
+SELECT metric_name, preferred_metric_name, metric_description
+FROM `sm-.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_name IN ('aov', 'mer', 'cac', 'roas')
+~~~
+```
+
+---
+
+## No access yet?
+
+If you cannot run queries due to permissions, see [BigQuery Access Request Template](/ai-analyst/agent-skills/bigquery-access-request-template).
+
+## Related docs
+
+
+
+ Setup and first-query fundamentals.
+
+
+ SourceMedium SQL templates and patterns.
+
+
+ Schema-level documentation for core tables.
+
+
+ 180+ pre-defined metrics with calculations.
+
+
+ Table availability, freshness, and column stats.
+
+
+ MTA models and experimental tables.
+
+
diff --git a/ai-analyst/building-trust.mdx b/ai-analyst/building-trust.mdx
new file mode 100644
index 0000000..83edcf4
--- /dev/null
+++ b/ai-analyst/building-trust.mdx
@@ -0,0 +1,146 @@
+---
+title: "Building Trust in AI Analytics"
+sidebarTitle: "Building Trust"
+description: "How to validate AI-generated insights and establish the AI Analyst as your source of truth"
+icon: "shield"
+---
+
+This guide explains how to validate AI Analyst results and establish a reliable workflow for using AI-generated analytics in your organization.
+
+## Why Validation Matters
+
+Generic AI tools (ChatGPT, Gemini, platform chatbots) don't query your actual data warehouse. When you ask them analytics questions, they may:
+
+| Issue | What Happens | Impact |
+|-------|--------------|--------|
+| **No data access** | Tool uses estimates or asks you to provide data | Answer is a guess, not a fact |
+| **Wrong data model** | Tool doesn't understand your attribution logic | Metrics don't match your actual definitions |
+| **Hallucinated joins** | AI invents relationships between tables | Numbers look plausible but are fabricated |
+| **Outdated context** | Tool trained on old data patterns | Doesn't reflect your current business |
+
+## How SourceMedium AI Analyst Is Different
+
+The AI Analyst queries your actual BigQuery warehouse:
+
+1. **Queries your actual data** — Every answer comes from SQL executed against BigQuery
+2. **Uses your data model** — Understands SourceMedium's attribution logic and metric definitions
+3. **Shows its work** — You see the exact SQL query, making results auditable
+4. **Validated schema** — Queries only tables and columns that exist in your warehouse
+
+## Validation Process
+
+Use this framework to validate AI Analyst results before relying on them for decisions.
+
+### Step 1: Define Your Key Questions
+
+Work with your data point of contact to identify **10-15 business questions** that matter most to your organization. These should be questions where getting the wrong answer would lead to bad decisions.
+
+**Example key questions:**
+- What was our blended ROAS last month?
+- What's our 90-day LTV by acquisition channel?
+- Which products have the highest repeat purchase rate?
+- What's our customer acquisition cost by channel?
+- How does subscription revenue compare to one-time revenue?
+
+### Step 2: Run Questions Through AI Analyst
+
+Ask each question to the AI Analyst and collect:
+- The natural language answer
+- The SQL query generated
+- The raw data returned
+- Any visualization produced
+
+### Step 3: Independent Validation
+
+Your data point of contact should **independently validate** each result:
+
+```sql
+-- Example: Validate the AI's ROAS calculation
+-- 1. Review the AI-generated SQL for logical correctness
+-- 2. Run the query manually in BigQuery
+-- 3. Cross-check against your dashboard or known benchmarks
+-- 4. Verify the time ranges and filters match your intent
+
+SELECT
+ SAFE_DIVIDE(SUM(sm_last_touch_revenue), SUM(ad_spend)) AS roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+```
+
+
+Focus validation on the SQL logic, not just the final number. A query can return a plausible-looking number while using the wrong joins or filters.
+
+
+### Step 4: Score and Document
+
+For each question, score the result:
+
+| Score | Meaning | Action |
+|-------|---------|--------|
+| ✅ **Correct** | SQL logic is sound, number matches validation | Approved for org-wide use |
+| ⚠️ **Partially correct** | Right approach, minor issues | Document the caveat, refine the question |
+| ❌ **Incorrect** | Wrong logic or significant error | Report via feedback, do not use |
+
+Document your validated questions as your organization's **canonical question set**. These become the questions everyone should use the AI Analyst for.
+
+### Step 5: Establish Organizational Policy
+
+Once your core questions are validated, establish clear guidelines:
+
+1. **Verified numbers must be traceable to the warehouse** — Any metrics cited in reports, decisions, or external communications should come from SourceMedium dashboards or validated AI Analyst queries (both query BigQuery)
+
+2. **Exploratory analysis can use any tool** — Quick hypothesis generation with Sidekick or ChatGPT is fine for exploration
+
+3. **Cite your source** — When reporting numbers, indicate whether it came from a validated AI Analyst query or exploratory analysis
+
+
+**Suggested policy**: Metrics cited in business decisions should come from SourceMedium dashboards or validated AI Analyst queries. Generic AI tools are useful for exploration but should not be cited as data sources.
+
+
+## Recommended Workflow
+
+1. **Explore** — Use any AI tool for quick hypothesis generation
+2. **Verify** — Confirm findings with AI Analyst (review the SQL)
+3. **Cite** — Use verified numbers in reports; keep the SQL for reproducibility
+
+## Ongoing Validation
+
+### Regular Re-validation
+- **Monthly**: Re-run your canonical question set to catch any drift
+- **After major changes**: Re-validate when you change attribution windows, add new data sources, or modify business logic
+
+### Feedback
+Every AI Analyst response includes a feedback button. Use it to report incorrect answers or flag issues—we review all feedback and use it to improve the system. See [Feedback](/ai-analyst#feedback) for details.
+
+### Automate Re-validation Today (DIY)
+If you want automated evaluation now, you can build a lightweight workflow using existing tools:
+
+1. **Save your canonical question set** — Copy the validated SQL from AI Analyst into a shared doc or version-controlled repo (one query per question).
+2. **Schedule re-runs** — Use BigQuery Scheduled Queries (or your existing orchestrator) to run those queries daily/weekly and write outputs into a small `ai_analyst_eval_runs` table.
+3. **Review drift** — Track changes across runs and re-validate when results move materially (often caused by upstream data backfills, attribution configuration changes, or logic updates).
+
+The goal of automation is not to “prove correctness forever,” but to catch drift early so your team re-validates before numbers make it into reports.
+
+## Summary
+
+| Tool Type | Best For | Trust Level for Reporting |
+|-----------|----------|---------------------------|
+| **Generic AI assistants** (ChatGPT, Gemini, platform chatbots) | Quick exploration, brainstorming | ❌ Do not cite |
+| **BI dashboards** | Curated views of validated metrics | ✅ Cite (queries warehouse) |
+| **SourceMedium AI Analyst** | Ad-hoc questions with SQL transparency | ✅ Cite after validation |
+
+The goal isn't to avoid other AI tools—they're useful for exploration. The goal is to ensure **numbers that inform decisions are traceable to your warehouse**. Both SourceMedium dashboards and the AI Analyst provide this traceability.
+
+---
+
+## Next Steps
+
+
+
+ See the full range of questions the AI Analyst handles.
+
+
+ Learn how to interpret responses, charts, and SQL output.
+
+
diff --git a/ai-analyst/diagnostics/attribution-health.mdx b/ai-analyst/diagnostics/attribution-health.mdx
new file mode 100644
index 0000000..558b253
--- /dev/null
+++ b/ai-analyst/diagnostics/attribution-health.mdx
@@ -0,0 +1,121 @@
+---
+title: "AI Analyst: Attribution Health"
+sidebarTitle: "Attribution Health"
+description: "Diagnose tracking quality and improve marketing attribution coverage"
+icon: "heart-pulse"
+---
+
+**Attribution Health answers: Is my marketing attribution accurate?**
+
+When you ask "How is my attribution health?", the AI Analyst runs a live audit against your orders data to show what percentage of purchases have attributable marketing touchpoints vs. showing as `(direct) / (none)`.
+
+## Why It Matters
+
+If a significant portion of your orders show as "direct" or "unattributed," you can't accurately measure which marketing channels are driving revenue. This affects:
+
+- **ROAS calculations** — Spend looks less efficient than it actually is
+- **Budget allocation** — You can't shift spend toward what's working
+- **Channel comparisons** — Organic and paid performance becomes unclear
+
+---
+
+## What the Audit Shows
+
+When you ask about attribution health, you'll see:
+
+| Metric | What It Means |
+|--------|---------------|
+| **Unattributed %** | Percentage of orders showing as `(direct) / (none)` |
+| **Top unattributed sources** | Breakdown of what "direct" traffic looks like |
+| **Trend** | Whether attribution coverage is improving or degrading |
+
+### Interpreting the Results
+
+| Unattributed % | Assessment |
+|----------------|------------|
+| **< 10%** | Healthy — your tracking captures most sources |
+| **10–25%** | Moderate — room to improve coverage |
+| **> 25%** | High — significant marketing attribution is missing |
+
+
+**Marketplace orders are excluded.** Attribution Health focuses on your direct-to-consumer (online DTC) orders — the ones where UTM tracking matters. Orders from Amazon, TikTok Shop, and other marketplaces are inherently attributed to that platform, so there's no UTM to capture.
+
+
+---
+
+## Common Causes of Poor Attribution
+
+
+
+ Campaigns without proper UTM tagging result in traffic appearing as direct.
+
+
+ Ad blockers, iOS privacy features, and browser restrictions prevent tracking.
+
+
+ Customers moving between domains lose UTM parameters along the way.
+
+
+ Long consideration cycles mean the original touchpoint expires before purchase.
+
+
+
+---
+
+## How to Improve Attribution
+
+For detailed guidance on improving your attribution coverage, see the full Attribution Health toolkit:
+
+
+ Comprehensive strategies for improving tracking: UTM setup, checkout attribute capture, post-purchase surveys, and more.
+
+
+### Quick Wins
+
+1. **Audit your UTM tagging** — Ensure all paid campaigns have consistent UTM parameters
+2. **Enable checkout attribute capture** — Capture UTMs at checkout to bypass cookie blockers (Shopify Plus)
+3. **Add post-purchase surveys** — Ask customers directly how they heard about you
+
+---
+
+## Example Questions
+
+- "How is my attribution health?"
+- "What's the health of my tracking?"
+- "Is my UTM coverage good?"
+- "Why is so much traffic direct/none?"
+- "What percentage of orders are unattributed?"
+
+---
+
+## Attribution Health vs Data Health
+
+| | Attribution Health | Data Health |
+|-|-------------------|-------------|
+| **Focus** | Tracking and UTM coverage quality | Table freshness and availability |
+| **Question it answers** | "Is my marketing attribution accurate?" | "Is my data pipeline working?" |
+| **Data source** | Live SQL audit of orders | Metadata about table freshness |
+| **What fixes it** | Fix UTM tagging, landing page parameters | Wait for sync, escalate integration issue |
+
+
+If Attribution Health looks poor but Data Health is fine, the issue is your tracking setup — not your data pipeline. Focus on UTM tagging and checkout attribute capture.
+
+
+---
+
+## Related Resources
+
+
+
+ Check whether your data tables are fresh and available.
+
+
+ Standardize UTM tagging for consistent attribution.
+
+
+ Deep dive into causes of missing attribution.
+
+
+ Capture UTMs at checkout to bypass cookie blockers.
+
+
diff --git a/ai-analyst/diagnostics/data-health.mdx b/ai-analyst/diagnostics/data-health.mdx
new file mode 100644
index 0000000..3cf22e0
--- /dev/null
+++ b/ai-analyst/diagnostics/data-health.mdx
@@ -0,0 +1,151 @@
+---
+title: "AI Analyst: Data Health"
+sidebarTitle: "Data Health"
+description: "Understand whether your data is fresh, available, and ready for analysis"
+icon: "stethoscope"
+---
+
+**Data Health answers one question: Is my data ready for analysis?**
+
+Before diving into revenue trends or cohort performance, you need to know whether the underlying data is complete and current. Data Health surfaces pipeline issues proactively so you can trust your answers, avoid surprises, and scope your analyses appropriately.
+
+## Why It Matters
+
+Analytics are only as reliable as the data behind them.
+
+- **Stale data misleads**: A "last 7 days" analysis is useless if the most recent 3 days haven't synced
+- **Proactive visibility prevents bad decisions**: Catching a sync issue before a board meeting is better than discovering it afterward
+- **Scoping saves time**: Knowing which domains are ready helps you focus on answerable questions
+
+
+Data Health tells you whether the pipeline is working. [Attribution Health](/ai-analyst/diagnostics/attribution-health) tells you whether your tracking is capturing marketing touchpoints. Both matter — a table can be perfectly fresh but still show 40% `(direct) / (none)` if UTM tracking isn't set up properly.
+
+
+---
+
+## What We Check
+
+| Dimension | What It Means |
+|-----------|---------------|
+| **Freshness** | Has the table been updated recently? We flag tables that haven't refreshed in 14+ days. |
+| **Availability** | Does the table contain data, or is it empty? |
+| **Domain Readiness** | Which analytical areas are usable — orders, customers, ads, attribution, etc.? |
+
+---
+
+## When Data Updates
+
+Key tables refresh daily. Our SLA guarantees **fresh data through the previous day** based on your reporting timezone.
+
+- **Through yesterday** — Complete and reliable. This is what we guarantee.
+- **Today's data** — Incomplete. Don't use current-day data for analysis.
+
+
+Real-time isn't the goal. We optimize for **accuracy over speed** — ensuring data is correctly transformed, deduplicated, and enriched before it reaches your warehouse.
+
+
+### Platform-Specific Timing
+
+Some platforms have longer sync windows due to API limitations:
+
+| Platform | Typical Lag |
+|----------|-------------|
+| Shopify, Klaviyo, Meta, Google Ads | 24 hours |
+| Amazon Seller/Vendor Central, Amazon Ads | 24–72 hours (API rate limits) |
+| GA4 | 24–48 hours |
+
+---
+
+## Why 14 Days?
+
+Key tables — orders, customers, sessions, ad spend — should have fresh data every day. That's the normal operating state for an active e-commerce business.
+
+The **14-day threshold** exists for secondary tables that may not see daily activity:
+
+- A new subscription program might not have orders every day yet
+- Refunds tables depend on actual refund volume
+- Some niche integrations only fire on specific events
+
+We flag tables at 14+ days because it's long enough to account for legitimate low-volume periods while still surfacing tables worth investigating.
+
+
+If a core table (orders, customers, ad performance) is stale, that's almost always a pipeline issue. If a secondary table is stale, check whether you'd expect activity — it might just be low volume.
+
+
+---
+
+## Common Scenarios
+
+| What You See | What It Likely Means |
+|--------------|----------------------|
+| Orders table is stale | E-commerce platform sync may be delayed or disconnected |
+| Attribution table fresh but coverage low | Pipeline works, but tracking may not — check [Attribution Health](/ai-analyst/diagnostics/attribution-health) |
+| Ad performance empty for a platform | That integration may not be connected |
+| Multiple tables 14+ days stale | Broader pipeline issue — recent analyses across domains are affected |
+| Single table stale, others fine | Platform-specific issue (API error, auth expiration, rate limits) |
+
+---
+
+## What To Do If Data Is Degraded
+
+
+
+ Ask "Which tables are stale?" to identify exactly what's affected. Is it one platform or multiple?
+
+
+ Avoid date ranges that depend on stale data. If orders haven't synced since Jan 15, don't analyze Jan 16–20.
+
+
+ If data is fresh but results look wrong (e.g., high `(direct) / (none)`), the issue may be tracking, not pipeline.
+
+
+ If staleness persists beyond 24–48 hours, reach out to your SourceMedium team — there may be an integration issue requiring admin attention.
+
+
+
+---
+
+## Example Questions
+
+You can ask about data health in natural language:
+
+- "How is my data health?"
+- "Can I trust my last 7 days of data?"
+- "Which tables are fresh?"
+- "What data do I have available?"
+- "Are my tables up to date?"
+- "When was my orders data last updated?"
+
+---
+
+## Data Health vs Attribution Health
+
+| | Data Health | Attribution Health |
+|-|-------------|-------------------|
+| **Focus** | Table freshness and availability | Tracking and UTM coverage quality |
+| **Question it answers** | "Is my data pipeline working?" | "Is my marketing attribution accurate?" |
+| **When to check** | Before any analysis | When results look wrong despite fresh data |
+| **What fixes it** | Wait for sync, or escalate integration issue | Fix UTM tagging, landing page parameters |
+
+
+**Check Data Health first.** If data is stale, that explains why numbers look off. If data is fresh but attribution seems wrong, then check Attribution Health.
+
+
+---
+
+## Related Resources
+
+
+
+ Diagnose and improve tracking coverage for marketing attribution.
+
+
+ Details on refresh schedules and platform-specific timing.
+
+
+ Common causes of missing attribution and how to fix them.
+
+
+ How SourceMedium structures and transforms your data.
+
+
diff --git a/ai-analyst/diagnostics/index.mdx b/ai-analyst/diagnostics/index.mdx
new file mode 100644
index 0000000..ac96f3c
--- /dev/null
+++ b/ai-analyst/diagnostics/index.mdx
@@ -0,0 +1,63 @@
+---
+title: "Diagnostics"
+sidebarTitle: "Overview"
+description: "Health checks to ensure your data is ready for analysis"
+icon: "stethoscope"
+---
+
+Before diving into analytics, it helps to know whether your data is complete and reliable. The AI Analyst includes built-in diagnostic checks that surface issues proactively.
+
+---
+
+## Two Types of Health Checks
+
+| Check | What It Answers |
+|-------|----------------|
+| **Data Health** | Is my data fresh and available? Are tables up to date? |
+| **Attribution Health** | Is my tracking working? Are marketing sources being captured? |
+
+These checks address different concerns:
+
+- **Data Health** is about your *data pipeline* — whether data is flowing from source systems to your warehouse
+- **Attribution Health** is about your *tracking setup* — whether UTM parameters and touchpoints are being captured correctly
+
+
+A table can be perfectly fresh but still show poor attribution. Conversely, tracking can be excellent but data stale. These are independent issues with different solutions.
+
+
+---
+
+## When to Run Diagnostics
+
+**Before starting an analysis:**
+Ask "How is my data health?" to confirm the tables you need are current.
+
+**When results look wrong:**
+If numbers seem off, check Data Health first (is the data stale?), then Attribution Health (is tracking capturing sources correctly?).
+
+**Proactively:**
+Run diagnostics periodically to catch issues before they affect decisions.
+
+---
+
+## Diagnostic Reports
+
+
+
+ Check table freshness, availability, and domain readiness. Answers: "Is my data pipeline working?"
+
+
+ Check UTM coverage, tracking quality, and unattributed traffic. Answers: "Is my marketing attribution accurate?"
+
+
+
+---
+
+## Quick Reference
+
+| Question | Diagnostic | What You Learn |
+|----------|-----------|----------------|
+| "How is my data health?" | Data Health | Table freshness, which domains are ready |
+| "Which tables are fresh?" | Data Health | Specific table-level status |
+| "How is my attribution health?" | Attribution Health | % of orders with attribution, tracking gaps |
+| "Why is traffic showing as direct/none?" | Attribution Health | Causes of missing attribution |
diff --git a/ai-analyst/index.mdx b/ai-analyst/index.mdx
new file mode 100644
index 0000000..b84c096
--- /dev/null
+++ b/ai-analyst/index.mdx
@@ -0,0 +1,218 @@
+---
+title: "AI Analyst"
+sidebarTitle: "Overview"
+description: "Ask questions about your data in natural language and get answers with charts and SQL"
+icon: "message-bot"
+---
+
+The AI Analyst lets you ask questions about your e-commerce data in plain English. It understands your question, finds the right data, writes SQL, and returns results with visualizations — all within Slack.
+
+## How It Works
+
+When you ask a question, the AI Analyst:
+
+1. **Classifies your question** — Determines whether you need data analysis, a definition, or a diagnostic check
+2. **Identifies relevant tables** — Finds the right data sources for your question
+3. **Generates SQL** — Writes a query against your BigQuery warehouse
+4. **Executes and visualizes** — Runs the query and creates a chart if appropriate
+
+
+The AI Analyst queries your actual data in BigQuery. Results reflect your real business metrics, not sample data.
+
+
+---
+
+## What You Can Ask
+
+The AI Analyst handles three types of questions:
+
+### Data Questions
+
+Questions that require querying your warehouse:
+
+- "What was our revenue last week?"
+- "Show me top 10 products by units sold this month"
+- "How many new customers did we acquire in January?"
+- "What's our average order value by channel?"
+
+### Definitions & Schema
+
+Questions about metrics, tables, data structure, and how SourceMedium works:
+
+- "What is LTV?"
+- "How is conversion rate calculated?"
+- "Which table has order data?"
+- "What columns are in the customers table?"
+- "How does attribution work in SourceMedium?"
+- "What's the difference between first-click and last-click attribution?"
+
+
+For these questions, the AI Analyst draws from [docs.sourcemedium.com](https://docs.sourcemedium.com) to provide accurate, up-to-date answers — no SQL required.
+
+
+### Diagnostics
+
+Health checks for your data and tracking:
+
+- "How is my data health?" — Check table freshness and availability
+- "How is my attribution health?" — Check UTM tracking coverage
+
+
+
+ Understand whether your data is fresh and ready for analysis.
+
+
+ Diagnose tracking gaps and improve attribution coverage.
+
+
+
+---
+
+## Analytical Domains
+
+The AI Analyst can query data across these domains:
+
+| Domain | What You Can Analyze |
+|--------|---------------------|
+| **Orders & Revenue** | Revenue, AOV, order counts, discounts, shipping |
+| **Customers** | New vs. repeat, cohort analysis, customer-level metrics |
+| **Marketing** | Ad spend, ROAS, CPO, channel performance |
+| **Email & SMS** | Campaign performance, engagement metrics |
+| **Web Analytics** | Funnel events, page views, conversion paths |
+| **Cohort LTV** | Lifetime value by acquisition cohort |
+| **Attribution** | Multi-touch attribution, channel contribution |
+
+---
+
+## Analysis Workflows
+
+The AI Analyst uses different workflows depending on your question type:
+
+| Question Type | Workflow |
+|--------------|----------|
+| Specific metrics | [Standard Analysis](/ai-analyst/workflows/standard) |
+| Open-ended/strategic | [Deep Analysis](/ai-analyst/workflows/deep-analysis) |
+| Definitions & schema | [Knowledge Retrieval](/ai-analyst/workflows/knowledge) |
+
+
+ Understand how different question types are routed and processed.
+
+
+### Deep Analysis
+
+For complex, open-ended questions — like "How can we improve our marketing performance?" or "What trends should we be aware of?" — the AI Analyst automatically engages **Deep Analysis**.
+
+In this mode, the AI breaks your question into multiple analytical perspectives, runs parallel Standard Analyses, and synthesizes the findings into a comprehensive answer.
+
+
+ Learn how Deep Analysis works, when it activates, and how to get the best results.
+
+
+---
+
+## Feedback
+
+Every response includes a **feedback button**. Use it to:
+
+- Rate whether the answer was helpful
+- Report issues or inaccuracies
+- Suggest improvements
+
+Your feedback directly improves the AI Analyst. We review feedback regularly to refine prompts, fix edge cases, and prioritize enhancements.
+
+---
+
+## Getting Started
+
+
+
+ Visit your tenant URL (`https://{your-tenant}.sourcemedium.com/slack/install`) and click "Add to Slack" to install the AI Analyst in your workspace. See [Setup & Installation](/ai-analyst/setup) for details.
+
+
+ Add the bot to a channel where you want to ask questions, or send it a direct message.
+
+
+ Type your question in natural language. Be specific about time ranges and metrics when possible.
+
+
+ The AI Analyst returns a response with data, a chart (if applicable), and the SQL query used.
+
+
+
+---
+
+## What It Can't Do
+
+The AI Analyst is designed for analytics questions against your SourceMedium data. It cannot:
+
+- Access systems outside your BigQuery warehouse
+- Modify data or run write operations
+- Answer questions unrelated to your e-commerce analytics
+- Guarantee real-time data (see [Data Health](/ai-analyst/diagnostics/data-health) for freshness)
+- Access custom tables or customized logic built on top of SourceMedium data
+
+---
+
+## Data Access & Security
+
+### Data Access Scope
+
+Currently, the AI Analyst has access only to **SourceMedium out-of-the-box transformed tables**. If you have built custom tables or added customized logic on top of our data within your BigQuery instance, the agent will not have visibility into those for now.
+
+
+Support for custom tables and user-defined schemas is planned for a future update.
+
+
+### Access Control
+
+The AI Analyst operates at the **tenant level**. This means:
+
+- **Full Tenant Visibility**: Anyone within your Slack workspace who has access to the bot can query any data available in the SourceMedium tables for your tenant.
+- **Multi-Store Organizations**: If your tenant includes multiple stores, the bot can query data across all of them.
+
+
+Granular access control (limiting specific users to specific stores or tables) is not yet available but is on our roadmap.
+
+
+---
+
+## Next Steps
+
+
+
+ See examples of questions across different domains.
+
+
+ Learn how to read responses, charts, and SQL output.
+
+
+ How to validate results and establish a reliable workflow.
+
+
+
+---
+
+## Related Resources
+
+The AI Analyst queries the same data that powers your SourceMedium dashboards. These resources help you understand the underlying data:
+
+
+
+ Definitions for all SourceMedium metrics.
+
+
+ Available dimensions for filtering and grouping.
+
+
+ Column-level documentation for all tables.
+
+
+
+
+
+ How we attribute orders to marketing channels.
+
+
+ How raw data becomes analytics-ready tables.
+
+
diff --git a/ai-analyst/roadmap.mdx b/ai-analyst/roadmap.mdx
new file mode 100644
index 0000000..c8fd58a
--- /dev/null
+++ b/ai-analyst/roadmap.mdx
@@ -0,0 +1,147 @@
+---
+title: "Roadmap"
+sidebarTitle: "Roadmap"
+description: "What's coming next for the AI Analyst"
+icon: "road"
+---
+
+The AI Analyst is actively evolving. This page outlines what's available today and what's coming next across two dimensions: **where you can use it** (interfaces) and **what it can do** (capabilities).
+
+---
+
+## Current Capabilities
+
+### Interface: Slack
+
+The AI Analyst is currently available in Slack. You can ask questions in your SourceMedium channel or via direct message.
+
+### Functionality: Ad-Hoc Questions
+
+Today, the AI Analyst handles **on-demand questions** — you ask, it answers. This includes:
+
+- **Straightforward queries**: "What was our revenue last week?"
+- **Complex analysis**: Open-ended questions that benefit from multiple analytical perspectives
+- **Definitions & schema**: "What is LTV?" or "Which table has order data?"
+- **Diagnostics**: Data Health and Attribution Health checks
+
+
+For complex questions, the AI Analyst automatically engages **Deep Analysis Mode**, exploring your question from multiple angles before synthesizing a comprehensive answer.
+
+
+---
+
+## What's Coming
+
+### New Interfaces
+
+
+
+ **Status: Coming Soon**
+
+ Connect the AI Analyst to any MCP-compatible client — including ChatGPT, Claude, Cursor, and other AI tools. Query your SourceMedium data from wherever you work.
+
+
+ **Status: Planned**
+
+ Receive scheduled insights delivered to your inbox. Useful for stakeholders who don't use Slack regularly.
+
+
+ **Status: Planned**
+
+ Ask questions and receive answers via text message. For quick access to your analytics when you're away from your desk.
+
+
+ **Status: Future**
+
+ Ask questions and receive answers via voice. For on-the-go access to your analytics.
+
+
+
+### New Capabilities
+
+
+
+ **Status: Planned**
+
+ Schedule regular analyses — daily revenue summaries, weekly channel performance, monthly cohort reports — delivered automatically to Slack or email.
+
+
+ **Status: Planned**
+
+ Proactive agents that monitor your data and surface insights without being asked. "Your Meta ROAS dropped 15% this week" or "You have 3 tables that haven't refreshed in 7 days."
+
+
+ **Status: Coming Soon**
+
+ Better charts with clearer labels, smarter axis choices, and support for multi-step visual stories that walk you through an analysis.
+
+
+ **Status: Planned**
+
+ The AI Analyst will remember insights from previous conversations, building context over time to provide more relevant answers.
+
+
+ **Status: Planned**
+
+ Connect the AI Analyst to your own custom BigQuery tables and proprietary logic. Define custom schemas that the agent can understand and query alongside SourceMedium's out-of-the-box data.
+
+
+ **Status: Planned**
+
+ Fine-grained permissions to control who can query what. Limit access by store, specific tables, or analytical domains at the user level.
+
+
+ **Status: Planned**
+
+ For organizations with multiple stores, scope questions to a specific store. "What was revenue for Store A last week?"
+
+
+ **Status: Planned**
+
+ Ask follow-up questions within a thread that build on previous answers. "Break that down by channel" after an initial revenue question.
+
+
+
+---
+
+## Capability Matrix
+
+| Capability | Status | Interface |
+|------------|--------|-----------|
+| Ad-hoc questions | **Available** | Slack |
+| Deep Analysis Mode | **Available** | Slack |
+| Data Health checks | **Available** | Slack |
+| Attribution Health checks | **Available** | Slack |
+| MCP Protocol support | **Coming Soon** | Any MCP client |
+| Improved visualizations | **Coming Soon** | All |
+| Recurring scheduled reports | Planned | Slack, Email |
+| Proactive background agents | Planned | Slack, Email |
+| Custom table support | Planned | All |
+| Granular access control | Planned | All |
+| Multi-store filtering | Planned | All |
+| Conversation follow-ups | Planned | All |
+| Email delivery | Planned | Email |
+| SMS & iMessage | Planned | SMS |
+| Voice interface | Future | Phone |
+
+---
+
+## What This Means For You
+
+### Short Term
+
+You can rely on the AI Analyst for **on-demand analysis** in Slack. Ask questions when you need answers, and the AI will query your data, generate SQL, and return results with visualizations.
+
+### Medium Term
+
+Expect **recurring reports** and **proactive monitoring** — the AI Analyst will start surfacing insights before you ask, catching anomalies and delivering scheduled summaries.
+
+### Long Term
+
+The AI Analyst becomes a **multi-channel analytics companion** — available wherever you are (Slack, email, SMS, voice, your favorite AI tool), proactively keeping you informed while remaining available for ad-hoc questions.
+
+---
+
+## Feedback
+
+Have ideas for what you'd like to see? Let your SourceMedium team know — the roadmap is shaped by customer needs.
diff --git a/ai-analyst/setup.mdx b/ai-analyst/setup.mdx
new file mode 100644
index 0000000..67f73e0
--- /dev/null
+++ b/ai-analyst/setup.mdx
@@ -0,0 +1,224 @@
+---
+title: "Setup & Installation"
+sidebarTitle: "Setup"
+description: "Prerequisites and installation steps for the AI Analyst"
+icon: "gear"
+---
+
+The AI Analyst queries your data in BigQuery through Slack. Before you can use it, your data infrastructure must be in place.
+
+## How It Works
+
+```mermaid
+flowchart LR
+ A[Your Data Sources] --> B[SourceMedium Pipeline] --> C[(BigQuery)] --> D[Dashboards & AI Analyst]
+```
+
+Your data flows from connected platforms (Shopify, Google Ads, Meta, GA4, etc.) through the SourceMedium pipeline into your BigQuery warehouse. The AI Analyst and your dashboards both query the same underlying data — they're just different interfaces.
+
+---
+
+## Prerequisites
+
+Before installing the AI Analyst, ensure your SourceMedium data pipeline is set up:
+
+
+
+ The AI Analyst queries data from your connected platforms. At minimum, you need:
+
+ - **E-commerce platform** (Shopify, Amazon Seller Central)
+ - **Marketing platforms** (Google Ads, Meta Ads, etc.)
+ - **Web analytics** (GA4)
+
+
+ See the full list of supported integrations.
+
+
+
+ After connecting integrations, SourceMedium ingests and transforms your data into BigQuery. This typically takes 24–72 hours for initial setup.
+
+ Your SourceMedium team will notify you when your data is ready. You can also check:
+ - Your Looker Studio dashboard is populated
+ - Or ask your SourceMedium team for confirmation
+
+
+ The AI Analyst queries the `sm_transformed_v2` dataset in your BigQuery project. Your SourceMedium team handles this provisioning — no action needed from you unless you're self-hosting.
+
+
+ Learn about your BigQuery data warehouse.
+
+
+
+
+
+If you're already using SourceMedium dashboards, your data infrastructure is ready — proceed to Slack installation.
+
+
+---
+
+## Slack Installation
+
+The AI Analyst is delivered as a Slack app called **SourceMedium**.
+
+
+In Slack, the bot appears as "SourceMedium" (or "SourceMedium (YourCompany)"). Throughout these docs, we refer to it as the "AI Analyst" to distinguish it from other SourceMedium products.
+
+
+### Your Tenant URL
+
+Each SourceMedium customer has a dedicated instance:
+
+```
+https://{your-tenant}.sourcemedium.com
+```
+
+For example, if your tenant ID is `acme`, your URL would be `https://acme.sourcemedium.com`.
+
+
+Not sure what your tenant ID is? It's typically your company name or a shortened version. Ask your SourceMedium team if you're unsure.
+
+
+### Installing the App
+
+
+
+ Go to `https://{your-tenant}.sourcemedium.com/slack/install`
+
+
+ You'll be redirected to Slack's authorization page.
+
+
+ See what the app can access (details below).
+
+
+ Click "Allow" to complete installation.
+
+
+ Mention the bot in a channel or send it a direct message.
+
+
+
+
+You must be a Slack workspace admin (or have app installation permissions) to install the AI Analyst.
+
+
+---
+
+## Permissions Requested
+
+When you install the app, Slack shows the permissions being requested:
+
+| Category | What It Enables |
+|----------|-----------------|
+| **Read messages** | See your questions in channels and DMs where the bot is present |
+| **Send messages** | Reply with results, charts, and SQL queries |
+| **Upload files** | Attach CSV exports, SQL files, and chart images |
+| **Read user info** | Identify who asked the question for context |
+| **Join channels** | Accept channel invitations when you add the bot |
+
+
+The bot only sees messages in channels where it's explicitly added or in direct messages sent to it. It cannot read messages in other channels.
+
+
+---
+
+## After Installation
+
+Once installed:
+
+1. **Invite the bot to a channel**: Use `/invite @SourceMedium` or add it from channel settings
+2. **Or use direct messages**: Send a DM to the SourceMedium bot for private queries
+3. **Ask a question**: Type your question in natural language
+
+The bot responds in a thread with your results.
+
+
+Many teams create a dedicated `#analytics` or `#data-questions` channel for queries. This keeps analytics discussions organized and lets the whole team learn from each other's questions.
+
+
+---
+
+## Access Control
+
+### Who Can Use It
+
+Anyone in your Slack workspace who can message the bot can query your data. There's no separate login — Slack authentication is used.
+
+### What Data Is Accessible
+
+The AI Analyst can query all SourceMedium out-of-the-box tables for your tenant:
+
+- Orders and revenue data
+- Customer information
+- Marketing and ad performance
+- Email and SMS metrics
+- Web analytics events
+- Attribution data
+
+
+Granular access control (limiting specific users to specific data) is not yet available. Anyone with access to the bot can query any data in your SourceMedium tables.
+
+
+### Multi-Store Organizations
+
+If your organization has multiple stores connected to SourceMedium, the AI Analyst can query data across all of them. Currently, queries return combined results across all stores in your tenant.
+
+
+Per-store filtering is on our [roadmap](/ai-analyst/roadmap). For now, include the store name in your question and the AI will attempt to filter appropriately if the data supports it.
+
+
+---
+
+## Troubleshooting
+
+### Data Issues
+
+**"I'm not seeing recent data"**
+- Check [Data Health](/ai-analyst/diagnostics/data-health) to verify table freshness
+- Data typically refreshes daily; check with your SourceMedium team for your refresh schedule
+
+**"The AI doesn't know about my tables"**
+- The AI Analyst only queries SourceMedium out-of-the-box tables
+- Custom tables or views you've created in BigQuery are not accessible
+
+### Installation Issues
+
+**"You don't have permission to install apps"**
+
+Ask your Slack workspace admin to either:
+- Install the app for you
+- Grant you app installation permissions
+
+**"This workspace is not authorized"**
+
+Your Slack workspace may not be linked to your SourceMedium tenant. Contact your SourceMedium team to verify the configuration.
+
+**Bot not responding after installation**
+
+1. Make sure the bot is invited to the channel you're messaging in
+2. Try sending a direct message to the bot instead
+3. Check that you're mentioning the bot correctly (`@SourceMedium`)
+
+---
+
+## Getting Help
+
+If you run into issues during setup:
+
+- **Email**: support@sourcemedium.com
+- **Slack**: Message your SourceMedium team in your shared channel
+
+Include your tenant ID and a description of the issue.
+
+---
+
+## Related Resources
+
+
+
+ Full onboarding guide for new SourceMedium customers.
+
+
+ Complete list of supported data sources.
+
+
diff --git a/ai-analyst/troubleshooting.mdx b/ai-analyst/troubleshooting.mdx
new file mode 100644
index 0000000..7878a96
--- /dev/null
+++ b/ai-analyst/troubleshooting.mdx
@@ -0,0 +1,149 @@
+---
+title: "Troubleshooting & FAQ"
+sidebarTitle: "Troubleshooting"
+description: "Common issues, questions, and how to resolve them"
+icon: "wrench"
+---
+
+This page covers common issues you might encounter when using the AI Analyst and answers frequently asked questions.
+
+---
+
+## Results Don't Match Expectations
+
+### The numbers seem wrong
+
+
+
+ Review the generated SQL query. The AI Analyst may have interpreted your time range differently than you intended. "Last week" could mean the previous 7 days or the previous calendar week.
+
+
+ Confirm the AI used the metric you expected. "Revenue" might be gross or net depending on context. Check the SQL to see exactly what was summed.
+
+
+ Ask "How is my data health?" — if the relevant tables are stale, recent data may be missing from results.
+
+
+
+### High (direct) / (none) in results
+
+This indicates an attribution issue, not a query issue. The AI Analyst is correctly reflecting what's in your data.
+
+
+ Learn how to diagnose and improve attribution coverage.
+
+
+---
+
+## The AI Misunderstood My Question
+
+### It answered a different question
+
+Rephrase with more specificity:
+
+| Instead of | Try |
+|------------|-----|
+| "How are we doing?" | "What was our revenue last 30 days vs. the previous 30 days?" |
+| "Show me sales" | "Show me daily order count for the past 2 weeks" |
+| "Best products" | "Top 10 products by revenue this month" |
+
+### It used the wrong table
+
+If the AI queried the wrong data source, clarify the domain:
+
+| Instead of | Try |
+|------------|-----|
+| "Show me performance" | "Show me ad performance by platform" |
+| "Customer data" | "Show me new customer acquisition by week" |
+
+---
+
+## No Results Returned
+
+### "No data found" or empty results
+
+1. **Check the date range** — You may be querying a period with no activity
+2. **Check filters** — The AI may have applied filters that excluded all rows
+3. **Check Data Health** — The table may be empty or not yet populated for your account
+
+### Query timed out
+
+Complex queries against large date ranges may time out. Try:
+
+- Narrowing the date range
+- Asking for aggregated data instead of row-level details
+- Breaking the question into smaller parts
+
+---
+
+## Chart Not Generated
+
+The AI Analyst generates charts when visualization adds value. Charts may not appear when:
+
+- The result is a single number (e.g., "total revenue was $142,350")
+- The data structure doesn't lend itself to visualization
+- There was an error generating the chart
+
+In these cases, the data is still returned as text or a table.
+
+---
+
+## Slow Responses
+
+Response time depends on:
+
+- **Query complexity** — Aggregations across large date ranges take longer
+- **Table size** — Some tables have more data than others
+- **Current load** — Occasional delays during peak usage
+
+Most queries complete within 1–2 minutes. If responses consistently take significantly longer, try simplifying your question or narrowing the scope.
+
+---
+
+## The AI Said It Can't Help
+
+The AI Analyst is designed for e-commerce analytics questions. It will decline requests that:
+
+- Ask about data outside your BigQuery warehouse
+- Request actions (modifying data, sending emails, etc.)
+- Are unrelated to analytics (general knowledge questions)
+
+For questions about SourceMedium concepts or definitions, the AI can still help — try rephrasing as a definition or schema question.
+
+---
+
+## Common Questions
+
+
+
+ Not yet. Each message starts a fresh session — the AI doesn't remember previous questions in the thread. If you want to drill down, include full context in your follow-up: "Show me revenue by channel for the last 30 days" rather than "Break that down by channel."
+
+ Conversation follow-ups are on our [roadmap](/ai-analyst/roadmap).
+
+
+ Most tables refresh daily. Our SLA guarantees fresh data through yesterday based on your reporting timezone. Today's data is not guaranteed. See [Data Health](/ai-analyst/diagnostics/data-health) for details.
+
+
+ Yes. Each response includes downloadable files: `query.sql` (the SQL used), `results.csv` (full data), and the chart image if one was generated.
+
+
+ Yes. Anyone in your Slack workspace with access to the bot can ask questions simultaneously. There's no queue or limit on concurrent users.
+
+
+ You shouldn't — everyone queries the same underlying data. If results differ, check:
+ - Are you asking about the same time range?
+ - Are you using the same metric definition?
+ - Did the data refresh between queries?
+
+
+
+---
+
+## Getting More Help
+
+If you're stuck:
+
+1. **Check the SQL** — The generated query often reveals how the AI interpreted your question
+2. **Try a simpler question** — Start basic, then add complexity
+3. **Ask about schema** — "Which table has order data?" can help you understand the data structure
+4. **Contact support** — Reach out to your SourceMedium team for persistent issues
diff --git a/ai-analyst/understanding-results.mdx b/ai-analyst/understanding-results.mdx
new file mode 100644
index 0000000..c3e3d33
--- /dev/null
+++ b/ai-analyst/understanding-results.mdx
@@ -0,0 +1,161 @@
+---
+title: "Understanding Results"
+sidebarTitle: "Reading Results"
+description: "How to interpret responses, charts, and SQL from the AI Analyst"
+icon: "chart-simple"
+---
+
+When the AI Analyst answers your question, it returns a structured response with multiple components. This page explains what each part means and how to use it.
+
+---
+
+## Response Components
+
+A typical response includes:
+
+| Component | Description |
+|-----------|-------------|
+| **Answer** | Natural language summary of the results |
+| **Chart** | Visual representation of the data (when applicable) |
+| **Data Table** | The underlying numbers in tabular format |
+| **SQL Query** | The exact query used to retrieve the data |
+
+---
+
+## The Answer
+
+The AI Analyst summarizes findings in plain language. This is designed to give you the key insight without needing to parse raw data.
+
+**Example:**
+
+> Your total revenue last week was $142,350, down 8% from the previous week. The top channel was Paid Social at $52,100 (37% of total).
+
+The answer prioritizes:
+- The specific number you asked for
+- Relevant context (comparisons, breakdowns)
+- Highlighting notable patterns
+
+---
+
+## Charts
+
+When your question lends itself to visualization, the AI Analyst generates a chart. Common chart types:
+
+| Chart Type | Used For |
+|------------|----------|
+| **Bar chart** | Comparisons across categories (channels, products, campaigns) |
+| **Line chart** | Trends over time (daily revenue, weekly orders) |
+| **Table** | Detailed breakdowns with multiple metrics |
+
+Charts are generated as images and posted directly in the Slack thread.
+
+
+If a chart doesn't appear, the AI Analyst determined the data was better presented as text or a table. This often happens for single-value answers or complex multi-dimensional data.
+
+
+---
+
+## Data Tables
+
+For questions that return multiple rows, you'll see a data table showing the raw results. This is the actual output from BigQuery, limited to a reasonable preview size.
+
+**Example:**
+
+| channel | revenue | orders |
+|---------|---------|--------|
+| Paid Social | 52,100 | 412 |
+| Email | 38,200 | 298 |
+| Organic Search | 28,750 | 215 |
+
+You can download the full dataset as a CSV file attached to the response.
+
+---
+
+## The SQL Query
+
+Every data response includes the SQL query used. This is useful for:
+
+- **Verification** — Confirm the AI understood your question correctly
+- **Learning** — See how to write similar queries yourself using SourceMedium table schemas
+- **Iteration** — Copy and modify the query in BigQuery for deeper follow-up analysis
+
+
+**Use the AI as a SQL tutor.** If you're learning BigQuery, comparing the generated SQL against our [Table Schemas](/data-activation/data-tables/sm_transformed_v2/index) is the fastest way to master your data structure. You can copy any query directly into the [BigQuery console](/onboarding/analytics-tools/bigquery-essentials) to test your own modifications.
+
+
+**Example:**
+
+```sql
+SELECT
+ sm_channel AS channel,
+ SUM(order_net_revenue) AS revenue,
+ COUNT(DISTINCT sm_order_key) AS orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) BETWEEN '2024-01-08' AND '2024-01-14'
+GROUP BY 1
+ORDER BY 2 DESC
+```
+
+
+If the results don't match your expectations, check the SQL to see how the AI Analyst interpreted your question. Date ranges and filters are common sources of misunderstanding.
+
+
+---
+
+## File Downloads
+
+Responses may include downloadable files:
+
+| File | Contents |
+|------|----------|
+| `query.sql` | The SQL query used |
+| `results.csv` | Full data export (not truncated) |
+| `chart.png` | The visualization as an image |
+
+These files are attached to the Slack message and can be downloaded directly.
+
+---
+
+## When Things Look Wrong
+
+If results don't match your expectations:
+
+
+
+ Review the SQL query to confirm the time period matches your intent.
+
+
+ Make sure the AI Analyst used the metric you expected (e.g., gross revenue vs. net revenue).
+
+
+ Ask "How is my data health?" to confirm the underlying tables are up to date.
+
+
+ If the AI misunderstood, rephrase with more specificity and try again.
+
+
+
+
+
+ Common issues and how to resolve them.
+
+
+ Verify your data is fresh before querying.
+
+
+
+---
+
+## Going Deeper
+
+Once you have results, you can explore further:
+
+
+
+ Learn to run and modify queries directly in BigQuery.
+
+
+ Build custom visualizations from your data.
+
+
diff --git a/ai-analyst/what-you-can-ask.mdx b/ai-analyst/what-you-can-ask.mdx
new file mode 100644
index 0000000..512dfb0
--- /dev/null
+++ b/ai-analyst/what-you-can-ask.mdx
@@ -0,0 +1,151 @@
+---
+title: "What You Can Ask"
+sidebarTitle: "Example Questions"
+description: "Example questions across different analytical domains"
+icon: "lightbulb"
+---
+
+The AI Analyst understands natural language questions about your e-commerce data. This page shows example questions organized by domain to help you get started.
+
+
+Be specific about time ranges when possible. "Last 30 days" is clearer than "recently."
+
+
+---
+
+## Orders & Revenue
+
+Questions about sales, order volume, and revenue metrics.
+
+```
+What was our total revenue last month?
+Show me daily revenue for the past 2 weeks
+How many orders did we have yesterday?
+What's our average order value this quarter vs last quarter?
+Top 10 days by revenue in 2024
+What was our revenue by channel last week?
+How much did we discount last month?
+```
+
+---
+
+## Customers
+
+Questions about customer acquisition, retention, and behavior.
+
+```
+How many new customers did we acquire last month?
+What's the split between new and repeat customers this year?
+Show me new customer acquisition by week for the past 3 months
+How many customers placed more than one order?
+What's our repeat purchase rate?
+```
+
+---
+
+## Marketing & Ads
+
+Questions about advertising performance and marketing spend.
+
+```
+What was our ROAS by channel last month?
+Show me ad spend by platform for the past 30 days
+Which campaigns had the best ROAS last week?
+What's our cost per acquisition by channel?
+Top 10 campaigns by attributed revenue
+How much did we spend on Meta ads in January?
+```
+
+---
+
+## Email & SMS
+
+Questions about outbound messaging performance.
+
+```
+Top 10 email campaigns by attributed revenue last 30 days
+What's our email open rate trend?
+Which SMS campaigns drove the most orders?
+Show me email performance by campaign type
+```
+
+---
+
+## Products
+
+Questions about product performance and mix.
+
+```
+Top 10 products by units sold this month
+Which products have the highest revenue?
+What's our best-selling product by channel?
+Show me product performance for [specific SKU]
+```
+
+---
+
+## Cohorts & LTV
+
+Questions about customer lifetime value and cohort behavior.
+
+```
+What's the LTV of customers acquired in Q1?
+Show me cohort retention by acquisition month
+How does LTV vary by first purchase channel?
+```
+
+---
+
+## Definitions & Schema
+
+Questions about what metrics mean, where data lives, and how SourceMedium works. These are answered using our documentation — no SQL required.
+
+```
+What is LTV?
+How do you calculate conversion rate?
+What does ROAS mean?
+Which table has order data?
+What columns are in the orders table?
+Where do I find email performance data?
+How does attribution work?
+What's the difference between first-click and last-click?
+How do I set up UTM tracking?
+What are the possible values for order_type?
+```
+
+---
+
+## Diagnostics
+
+Health checks for your data and tracking.
+
+```
+How is my data health?
+Which tables are fresh?
+Are my tables up to date?
+How is my attribution health?
+Why is so much traffic direct/none?
+```
+
+
+ Understand Data Health and Attribution Health checks in detail.
+
+
+---
+
+## Tips for Better Results
+
+
+
+ Instead of "recently" or "lately," use specific ranges like "last 7 days," "in January," or "Q4 2024."
+
+
+ "Revenue" is clearer than "sales." "Orders" is clearer than "transactions." Use the terminology from your dashboards.
+
+
+ Complex multi-part questions work better as separate queries. Ask "What was our revenue last month?" then "How does that compare to the previous month?"
+
+
+ "Top 10 products by revenue" is specific. "Best products" is ambiguous.
+
+
diff --git a/ai-analyst/workflows/deep-analysis.mdx b/ai-analyst/workflows/deep-analysis.mdx
new file mode 100644
index 0000000..75d9035
--- /dev/null
+++ b/ai-analyst/workflows/deep-analysis.mdx
@@ -0,0 +1,151 @@
+---
+title: "Deep Analysis"
+sidebarTitle: "Deep Analysis"
+description: "How the AI Analyst handles complex, open-ended questions with multi-perspective analysis"
+icon: "brain"
+---
+
+When you ask a strategic or exploratory question, the AI Analyst automatically activates **Deep Analysis** — a thorough approach that runs multiple analyses in parallel before synthesizing a comprehensive answer.
+
+---
+
+## When Deep Analysis Activates
+
+Deep Analysis is triggered automatically for **open-ended questions** — questions that don't have a single, specific answer and benefit from exploring multiple perspectives.
+
+### Questions That Trigger Deep Analysis
+
+```
+How can we improve our marketing performance?
+What trends should we be paying attention to?
+Why are our metrics declining?
+What opportunities am I missing?
+How is our business performing overall?
+What should we focus on to grow revenue?
+```
+
+These questions require the AI to:
+- Consider multiple dimensions of your data
+- Compare across time periods, channels, and segments
+- Identify patterns that might not be obvious from a single query
+- Synthesize findings into actionable insights
+
+### Questions That Use Standard Analysis
+
+```
+What was our revenue last week?
+Top 10 products by units sold
+How many new customers in January?
+What's our ROAS by channel?
+```
+
+Specific questions with clear metrics and time ranges use the faster [Standard Analysis](/ai-analyst/workflows/standard) workflow.
+
+---
+
+## How It Works
+
+Deep Analysis is essentially **multiple Standard Analyses running in parallel**, with a synthesis step at the end:
+
+
+
+ The AI breaks your open-ended question into 2–3 specific analytical questions that together address your original query from different angles.
+
+ **Example:** For "How can we improve marketing performance?", the AI might generate:
+ - "Which channels have the best ROAS and how has that changed recently?"
+ - "Which campaigns are driving new customers vs. repeat customers?"
+ - "Where are we overspending relative to attributed revenue?"
+
+
+ The AI runs multiple Standard Analyses simultaneously — one for your original question plus each strategic question. Each follows the full workflow: identifying tables, writing SQL, executing queries, and analyzing results.
+
+
+ After all analyses complete, the AI synthesizes the findings into a cohesive response:
+ - Key insights from each perspective
+ - Patterns that emerged across the analyses
+ - Specific recommendations backed by data
+ - Relevant charts and data tables
+
+
+
+---
+
+## What You'll See
+
+When Deep Analysis is active, the AI Analyst shows progress through each phase:
+
+| Status | What's Happening |
+|--------|------------------|
+| 🔍 Understanding your question | Classifying and determining the analysis approach |
+| 🧠 Deep Analysis activated | Open-ended question detected, entering multi-perspective mode |
+| 🧠 Generating strategic questions | Breaking down your question into analytical angles |
+| 🔄 Running parallel analyses | Executing multiple SQL queries simultaneously |
+| ✨ Synthesizing insights | Combining results into a comprehensive answer |
+
+
+Deep Analysis takes longer than Standard Analysis but provides richer, more actionable insights.
+
+
+---
+
+## Example: Deep Analysis in Action
+
+**Question:** "How can we improve our marketing performance?"
+
+**What Deep Analysis Does:**
+
+1. **Generates strategic sub-questions:**
+ - "Which channels have the highest and lowest ROAS over the past 30 days?"
+ - "What's the new customer acquisition cost by channel?"
+ - "Which campaigns are underperforming relative to spend?"
+
+2. **Runs parallel analyses** for each question, querying:
+ - Ad performance data by channel
+ - Customer acquisition metrics
+ - Campaign-level ROAS and spend
+
+3. **Synthesizes findings:**
+ > "Your Meta campaigns are delivering 3.2x ROAS, outperforming Google Ads at 1.8x. However, Google is driving 40% of new customer acquisitions at a lower CAC ($32 vs $45). Consider reallocating 15% of Meta budget to Google's top-performing campaigns to balance immediate ROAS with customer acquisition."
+
+---
+
+## Tips for Better Results
+
+
+
+ Deep Analysis works best when your question truly requires exploration. "What should I focus on?" is better than "Show me revenue" for triggering multi-perspective analysis.
+
+
+ "How can we improve Q1 performance given we're launching a new product line?" gives the AI useful context for generating relevant strategic questions.
+
+
+ After a Deep Analysis, ask follow-up questions in the same thread. The AI retains context and can dive deeper into specific findings.
+
+
+ Deep Analysis takes longer but surfaces insights you might not get from a single query. The synthesis phase is where the real value emerges.
+
+
+
+---
+
+## Limitations
+
+- **Scope:** Currently limited to 2–3 parallel analyses to balance depth with speed
+- **Visualizations:** Charts are generated for the synthesized response, not each individual analysis
+
+
+If you need a quick, specific answer, phrase your question to avoid Deep Analysis. "What was our Meta ROAS last month?" will return faster than "How is Meta performing?"
+
+
+---
+
+## Related
+
+
+
+ How specific data queries are handled.
+
+
+ How definition and schema questions work.
+
+
diff --git a/ai-analyst/workflows/index.mdx b/ai-analyst/workflows/index.mdx
new file mode 100644
index 0000000..f68a78f
--- /dev/null
+++ b/ai-analyst/workflows/index.mdx
@@ -0,0 +1,131 @@
+---
+title: "Analysis Workflows"
+sidebarTitle: "Workflows"
+description: "How the AI Analyst handles different types of questions with specialized workflows"
+icon: "diagram-project"
+---
+
+The AI Analyst uses different workflows depending on what you're asking. Each workflow is optimized for its type of question — from quick knowledge lookups to comprehensive multi-perspective analyses.
+
+---
+
+## How Questions Are Routed
+
+When you send a message, the AI Analyst classifies it into one of three categories:
+
+| Question Type | Workflow |
+|--------------|----------|
+| **Specific data requests** | [Standard Analysis](/ai-analyst/workflows/standard) |
+| **Open-ended / strategic** | [Deep Analysis](/ai-analyst/workflows/deep-analysis) |
+| **Definitions & concepts** | [Knowledge Retrieval](/ai-analyst/workflows/knowledge) |
+
+The classification happens automatically based on the question's structure and intent.
+
+---
+
+## Workflow Overview
+
+
+
+ Single-path SQL analysis for specific metrics and time ranges. One question, one query, one answer.
+
+
+ Multi-perspective analysis for strategic questions. Runs multiple Standard Analyses in parallel and synthesizes insights.
+
+
+ Instant answers about metrics, tables, and concepts. Draws from SourceMedium documentation and metadata.
+
+
+
+---
+
+## Choosing the Right Approach
+
+### For Data Answers
+
+Ask specific, bounded questions:
+
+```
+What was our revenue last week?
+Top 10 products by units sold this month
+What's our ROAS by channel for the past 30 days?
+```
+
+These trigger **Standard Analysis** for quick results.
+
+### For Strategic Insights
+
+Ask open-ended, exploratory questions:
+
+```
+How can we improve our marketing performance?
+What trends should we be watching?
+Why are our metrics declining?
+```
+
+These trigger **Deep Thinking** for comprehensive analysis.
+
+### For Definitions & Concepts
+
+Ask about metrics, tables, or how things work:
+
+```
+What is LTV?
+How is ROAS calculated?
+Which table has order data?
+```
+
+These trigger **Knowledge Retrieval** for instant documentation-backed answers.
+
+---
+
+## Workflow Comparison
+
+| Feature | Standard | Deep Thinking | Knowledge |
+|---------|----------|---------------|-----------|
+| **Data Source** | BigQuery | BigQuery | Docs + Metadata |
+| **SQL Queries** | 1 | 2–4 | 0 (usually) |
+| **Parallel Execution** | No | Yes | No |
+| **Charts** | Yes | Yes | No |
+| **Best For** | Specific metrics | Strategic questions | Learning concepts |
+
+---
+
+## How Classification Works
+
+The AI uses contextual signals to determine the right workflow:
+
+**Standard Analysis triggers:**
+- Specific time ranges ("last week", "in January")
+- Named metrics with data requests ("revenue", "orders", "ROAS")
+- Rankings and comparisons ("top 10", "vs last month")
+- Computed results ("by channel", "trend over time")
+
+**Deep Thinking triggers:**
+- "How can we improve..." questions
+- "What should we focus on..." questions
+- Trend analysis without specific bounds
+- Strategy and optimization requests
+
+**Knowledge Retrieval triggers:**
+- "What is..." or "What does...mean"
+- "How is X calculated?"
+- "Which table has..." or "What columns..."
+- Data health and attribution health questions
+
+
+If you want to override the classification, be explicit. "Just give me the revenue numbers" will use Standard Analysis even if your phrasing might otherwise trigger Deep Thinking.
+
+
+---
+
+## Related
+
+
+
+ How to read responses, charts, and SQL output.
+
+
+ See examples across all domains and workflows.
+
+
diff --git a/ai-analyst/workflows/knowledge.mdx b/ai-analyst/workflows/knowledge.mdx
new file mode 100644
index 0000000..f50807c
--- /dev/null
+++ b/ai-analyst/workflows/knowledge.mdx
@@ -0,0 +1,184 @@
+---
+title: "Knowledge Retrieval"
+sidebarTitle: "Knowledge Retrieval"
+description: "How the AI Analyst answers definition, schema, and conceptual questions"
+icon: "book"
+---
+
+For questions about metrics, tables, and how SourceMedium works, the AI Analyst uses **Knowledge Retrieval** — providing instant answers from documentation and metadata without querying your warehouse.
+
+---
+
+## When Knowledge Retrieval Is Used
+
+Knowledge Retrieval handles questions about **definitions, concepts, and schema** — anything that can be answered from SourceMedium documentation rather than your warehouse data.
+
+### Examples
+
+```
+What is LTV?
+How is ROAS calculated?
+What does conversion rate mean?
+Which table has order data?
+What columns are in the customers table?
+How does attribution work?
+What's the difference between first-click and last-click?
+How do I set up UTM tracking?
+```
+
+These questions share key characteristics:
+- **"What is" / "How does"** phrasing
+- **Metric definitions** (LTV, ROAS, AOV)
+- **Schema questions** (tables, columns)
+- **How SourceMedium works**
+
+---
+
+## How It Works
+
+
+
+ The AI recognizes that your question is about concepts or schema, not about querying data.
+
+
+ The question is matched against SourceMedium documentation and metadata.
+
+
+ The AI synthesizes a clear answer from the relevant sources, formatted for Slack.
+
+
+
+---
+
+## What You'll See
+
+Knowledge Retrieval responses include:
+
+| Component | Description |
+|-----------|-------------|
+| **Answer** | Clear explanation of the concept or term |
+| **Source** | Links to relevant documentation pages |
+| **Context** | Related concepts you might want to explore |
+
+
+No SQL is generated for Knowledge Retrieval questions. The answer comes directly from documentation and metadata.
+
+
+---
+
+## Question Categories
+
+### Metric Definitions
+
+```
+What is LTV?
+How is ROAS calculated?
+What does AOV mean?
+How is conversion rate defined?
+```
+
+The AI explains what the metric measures, how it's calculated, and where you can find it in your data.
+
+### Schema & Tables
+
+```
+Which table has order data?
+What columns are in obt_orders?
+Where do I find customer information?
+What's the difference between dim_orders and obt_orders?
+```
+
+The AI describes table purposes, key columns, and when to use each table.
+
+### SourceMedium Concepts
+
+```
+How does attribution work?
+What's the difference between first-click and last-click?
+How do I set up UTM tracking?
+What is the attribution source hierarchy?
+```
+
+The AI explains SourceMedium-specific methodology and configuration.
+
+### Data Structures
+
+```
+What are the possible values for order_type?
+How is sales_channel determined?
+What does sm_default_channel mean?
+```
+
+The AI explains dimension values, enums, and how data is categorized.
+
+---
+
+## Tips for Knowledge Questions
+
+
+
+ "What is LTV?" triggers Knowledge Retrieval. "What was our LTV last month?" triggers Standard Analysis.
+
+
+ Schema questions are answered from documentation, not by querying metadata.
+
+
+ After getting a definition, you can ask follow-up questions: "How do I calculate that in SQL?" or "Show me an example."
+
+
+
+---
+
+## From Knowledge to Analysis
+
+After understanding a concept, you can immediately apply it:
+
+**Knowledge:** "What is ROAS?"
+> ROAS (Return on Ad Spend) is calculated as attributed revenue divided by ad spend...
+
+**Follow-up:** "What was our ROAS by channel last month?"
+> The AI now runs a Standard Analysis query to get your actual ROAS data.
+
+
+The AI retains conversation context. If you ask about a concept and then want to see your data, it connects the two.
+
+
+---
+
+## Knowledge Sources
+
+Knowledge Retrieval draws from:
+
+- **Data Dictionary** — Metrics and dimensions
+- **Table Schemas** — Column definitions and relationships
+- **Core Concepts** — Attribution, data transformations
+- **Integration Guides** — Platform-specific information
+- **FAQs** — Common questions and troubleshooting
+
+---
+
+## Related
+
+
+
+ How specific data queries are handled.
+
+
+ How open-ended questions trigger multi-perspective analysis.
+
+
+
+---
+
+## Explore the Knowledge Base
+
+These are the sources the AI draws from for Knowledge Retrieval:
+
+
+
+ Definitions of common terms and acronyms.
+
+
+ How SourceMedium attributes orders to channels.
+
+
diff --git a/ai-analyst/workflows/standard.mdx b/ai-analyst/workflows/standard.mdx
new file mode 100644
index 0000000..3fa8eaa
--- /dev/null
+++ b/ai-analyst/workflows/standard.mdx
@@ -0,0 +1,141 @@
+---
+title: "Standard Analysis"
+sidebarTitle: "Standard Analysis"
+description: "How the AI Analyst handles specific data questions with fast, focused queries"
+icon: "bolt"
+---
+
+For questions with specific metrics and time ranges, the AI Analyst uses **Standard Analysis** — a streamlined workflow that quickly retrieves your data and generates insights.
+
+---
+
+## When Standard Analysis Is Used
+
+Standard Analysis handles **specific questions** — questions that can be answered with a single SQL query against your data.
+
+### Examples
+
+```
+What was our revenue last week?
+Top 10 products by units sold this month
+How many new customers in January?
+What's our ROAS by channel for the past 30 days?
+Show me daily orders for the past 2 weeks
+Which campaigns had the best performance yesterday?
+```
+
+These questions share key characteristics:
+- **Specific metrics** (revenue, orders, customers, ROAS)
+- **Clear time bounds** (last week, this month, past 30 days)
+- **Focused scope** (one dimension or ranking)
+
+---
+
+## How It Works
+
+Standard Analysis follows a four-step pipeline:
+
+
+
+ The AI determines which BigQuery tables contain the data you need. For an orders question, it routes to `obt_orders`; for campaign metrics, it uses `rpt_ad_performance_daily`.
+
+
+ Using your question and the relevant table schemas, the AI writes a SQL query. This includes appropriate filters, aggregations, and ordering.
+
+
+ The query runs against your BigQuery warehouse. Results are validated and any data quality issues are flagged.
+
+
+ The AI creates a natural language summary, determines if a chart would be helpful, and packages everything into a Slack response.
+
+
+
+---
+
+## What You'll See
+
+During Standard Analysis, the AI shows progress through each phase:
+
+| Status | What's Happening |
+|--------|------------------|
+| 🔍 Understanding your question | Classifying the question type |
+| 📊 Identifying relevant tables | Finding the right data sources |
+| ✍️ Writing SQL query | Generating the query |
+| ⚡ Executing query | Running against BigQuery |
+| 📈 Generating chart | Creating visualization (if applicable) |
+| ✅ Results ready | Response complete |
+
+
+---
+
+## Response Components
+
+A Standard Analysis response includes:
+
+| Component | Description |
+|-----------|-------------|
+| **Summary** | Natural language answer to your question |
+| **Data Table** | The actual numbers, limited for readability |
+| **Chart** | Visual representation (when appropriate) |
+| **SQL Query** | The exact query used (downloadable) |
+| **CSV Export** | Full data export (downloadable) |
+
+---
+
+## Tips for Best Results
+
+
+
+ "Last 30 days" is clearer than "recently." The AI handles relative dates well: "yesterday," "last week," "past quarter," "YTD."
+
+
+ "Revenue" is clearer than "sales." "Orders" is clearer than "transactions." Use terminology from your dashboards.
+
+
+ "Top 10 products by revenue" gives a focused answer. "Best products" is ambiguous and may trigger Deep Analysis.
+
+
+ "What was revenue and how did AOV change?" works better as two separate questions. Keep each query focused.
+
+
+
+---
+
+## When to Use Standard vs. Deep Analysis
+
+| Standard Analysis | Deep Analysis |
+|------------------|---------------|
+| What was revenue last week? | How can we improve revenue? |
+| Top 10 campaigns by ROAS | Why is our marketing underperforming? |
+| New customer count by month | What customer trends should we focus on? |
+| AOV by channel | How should we optimize our channel mix? |
+
+
+If you phrase a question specifically, it stays in Standard Analysis. "What was our Meta ROAS last month?" is faster than "How is Meta performing?"
+
+
+---
+
+## Related
+
+
+
+ How open-ended questions trigger multi-perspective analysis.
+
+
+ How definition and schema questions are handled.
+
+
+
+---
+
+## Learn More About Your Data
+
+
+
+ See what columns are available in each table.
+
+
+ Understand how each metric is calculated.
+
+
diff --git a/data-activation/data-tables/sm_experimental/index.mdx b/data-activation/data-tables/sm_experimental/index.mdx
new file mode 100644
index 0000000..d3ec450
--- /dev/null
+++ b/data-activation/data-tables/sm_experimental/index.mdx
@@ -0,0 +1,25 @@
+---
+title: "SM Experimental Tables"
+description: "Browse tables in the sm_experimental schema—preview features and advanced analytics models."
+icon: "flask"
+---
+
+The `sm_experimental` schema contains tables for preview features and advanced analytics models. These tables are production-ready but may evolve as features mature.
+
+
+Tables in `sm_experimental` may have schema changes without a deprecation window. For updates, contact your SourceMedium Customer Solution Analyst.
+
+
+### Multi-Touch Attribution
+
+
+ Daily ad performance with waterfall MTA attribution at ad, ad group, campaign, and channel levels.
+
+
+ Customer purchase journeys with multi-touch attribution calculations across multiple dimensions and models.
+
+
+
+
+
+Need a table promoted to `sm_transformed_v2`? Contact your SourceMedium account manager.
diff --git a/data-activation/data-tables/sm_experimental/obt_purchase_journeys_with_mta_models.mdx b/data-activation/data-tables/sm_experimental/obt_purchase_journeys_with_mta_models.mdx
new file mode 100644
index 0000000..abc80e8
--- /dev/null
+++ b/data-activation/data-tables/sm_experimental/obt_purchase_journeys_with_mta_models.mdx
@@ -0,0 +1,417 @@
+---
+title: 'obt_purchase_journeys_with_mta_models'
+description: 'Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations across multiple dimensions.'
+icon: "table"
+---
+
+This is the central model for multi-touch attribution, containing complete customer journey data with attribution calculations across multiple dimensions and models.
+
+## Key Features
+
+- **Multi-dimensional attribution**: Marketing channel, landing page, ad, campaign, ad group, and email/SMS
+- **Three attribution models**: First touch, last touch, and linear
+- **Journey metadata**: Session count, days to conversion, journey type classification
+- **Deduplication flags**: Ensure unique contributions per session for linear attribution
+
+
+Email/SMS touches are excluded from first touch and linear attribution but can receive last touch attribution for configured customers.
+
+
+## Key Columns
+
+```yaml
+version: 2
+
+models:
+ - name: obt_purchase_journeys_with_mta_models
+ description: >
+ Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations.
+ Grain: One row per touchpoint (sm_touch_id). Date field: event_local_datetime.
+ Critical filters: sm_event_name = 'purchase' for conversion rows; is_valid_touch.* for dimension-specific valid touches.
+ columns:
+ - name: sm_store_id
+ description: >
+ SourceMedium store identifier (brand/workspace).
+
+ - name: source_system
+ description: >
+ Event tracking platform emitting the touchpoint (elevar, snowplow, heap, etc.).
+
+ - name: sm_touch_id
+ description: >
+ Unique identifier for each touchpoint in the customer journey. Primary key.
+
+ - name: event_user_id
+ description: >
+ User identifier from the event tracking system for journey attribution.
+
+ - name: sm_event_name
+ description: >
+ Standardized event name (page_view, purchase, add_to_cart, etc.).
+
+ - name: event_local_datetime
+ description: >
+ Event timestamp in the reporting timezone for time-based attribution.
+
+ - name: valid_event_index_to_next_purchase
+ description: >
+ Sequence index from this touchpoint to the next purchase event.
+
+ - name: is_valid_touch
+ description: >
+ Struct indicating whether touch is valid for each attribution dimension (marketing_channel, landing_page, ad, email_sms, campaign, ad_group).
+
+ - name: unique_dimension_value_count
+ description: >
+ Count of distinct dimension values in the purchase journey.
+
+ - name: ad_platform_metadata
+ description: >
+ Struct containing ad platform metadata (ad_id, ad_name, platform details).
+
+ - name: campaign_platform_metadata
+ description: >
+ Struct containing campaign platform metadata (campaign_id, campaign_name, etc.).
+
+ - name: ad_group_platform_metadata
+ description: >
+ Struct containing ad group platform metadata (ad_group_id, ad_group_name, etc.).
+
+ - name: purchase_session_count
+ description: >
+ Number of distinct sessions in the purchase journey from first touch to conversion.
+
+ - name: order_metadata
+ description: >
+ Struct containing order metadata fields (order_id, customer details, etc.).
+
+ - name: dimension_value
+ description: >
+ Struct containing the dimension value of the touch for each attribution dimension.
+
+ - name: dimension_value.marketing_channel
+ description: >
+ Marketing channel dimension value for this touchpoint.
+
+ - name: dimension_value.landing_page
+ description: >
+ Landing page URL path for this touchpoint.
+
+ - name: dimension_value.ad
+ description: >
+ Ad identifier for this touchpoint.
+
+ - name: dimension_value.email_sms
+ description: >
+ Email or SMS campaign identifier for this touchpoint.
+
+ - name: dimension_value.campaign
+ description: >
+ Campaign identifier for this touchpoint.
+
+ - name: dimension_value.ad_group
+ description: >
+ Ad group identifier for this touchpoint.
+
+ - name: purchase_order_id
+ description: >
+ Order ID of the purchase event this touchpoint contributed to.
+
+ - name: purchase_order_revenue
+ description: >
+ Total revenue from the purchase order for attribution calculations.
+
+ - name: purchase_local_datetime
+ description: >
+ Purchase event timestamp in the reporting timezone for conversion attribution.
+
+ - name: linear_model_multiplier
+ description: >
+ Struct containing linear attribution multipliers for each dimension based on valid touch count.
+
+ - name: valid_touch_count
+ description: >
+ Struct containing count of valid touches for each dimension.
+
+ - name: valid_touch_count.marketing_channels
+ description: >
+ Count of valid non-brand marketing channel touches in the purchase journey.
+
+ - name: valid_touch_count.landing_pages
+ description: >
+ Count of valid landing page touches in the purchase journey.
+
+ - name: valid_touch_count.ads
+ description: >
+ Count of valid non-brand ad touches in the purchase journey.
+
+ - name: valid_touch_count.campaigns
+ description: >
+ Count of valid non-brand campaign touches in the purchase journey.
+
+ - name: valid_touch_count.ad_groups
+ description: >
+ Count of valid non-brand ad group touches in the purchase journey.
+
+ - name: valid_touch_count.email_sms
+ description: >
+ Count of valid email/SMS touches in the purchase journey.
+
+ - name: sm_is_purchase_attributable_by
+ description: >
+ Struct indicating which dimensions this purchase can be attributed by based on business rules.
+
+ - name: sm_is_purchase_attributable_by_last_touch
+ description: >
+ Struct indicating which dimensions allow last touch attribution for this purchase.
+
+ - name: purchase_journey_type
+ description: >
+ Categorizes the purchase journey: single_session, same_day_multi_session, or multi_day_multi_session.
+
+ - name: days_to_conversion
+ description: >
+ Struct containing days between first touch and purchase conversion for each attribution dimension.
+
+ - name: days_to_conversion.marketing_channel
+ description: >
+ Days between first valid marketing channel touch and purchase.
+
+ - name: days_to_conversion.landing_page
+ description: >
+ Days between first valid landing page touch and purchase.
+
+ - name: days_to_conversion.ad
+ description: >
+ Days between first valid ad touch and purchase.
+
+ - name: days_to_conversion.email_sms
+ description: >
+ Days between first valid email/sms touch and purchase.
+
+ - name: days_to_conversion.campaign
+ description: >
+ Days between first valid campaign touch and purchase.
+
+ - name: days_to_conversion.ad_group
+ description: >
+ Days between first valid ad group touch and purchase.
+
+ - name: first_touch_dimension_value
+ description: >
+ Struct containing the dimension values for the first valid touch in each attribution dimension.
+
+ - name: last_touch_dimension_value
+ description: >
+ Struct containing the dimension values for the last valid touch in each attribution dimension.
+
+ - name: first_touch_revenue_impact
+ description: >
+ Struct containing revenue attributed to this touchpoint if it was the first touch for each dimension.
+
+ - name: first_touch_revenue_impact.marketing_channel
+ description: >
+ Revenue attributed to this touchpoint as first touch for the marketing channel dimension.
+
+ - name: first_touch_revenue_impact.landing_page
+ description: >
+ Revenue attributed to this touchpoint as first touch for the landing page dimension.
+
+ - name: first_touch_revenue_impact.ad
+ description: >
+ Revenue attributed to this touchpoint as first touch for the ad dimension.
+
+ - name: first_touch_revenue_impact.campaign
+ description: >
+ Revenue attributed to this touchpoint as first touch for the campaign dimension.
+
+ - name: first_touch_revenue_impact.ad_group
+ description: >
+ Revenue attributed to this touchpoint as first touch for the ad group dimension.
+
+ - name: first_touch_revenue_impact.email_sms
+ description: >
+ Revenue attributed to this touchpoint as first touch for the email/SMS dimension.
+
+ - name: last_touch_revenue_impact
+ description: >
+ Struct containing revenue attributed to this touchpoint if it was the last touch for each dimension.
+
+ - name: last_touch_revenue_impact.marketing_channel
+ description: >
+ Revenue attributed to this touchpoint as last touch for the marketing channel dimension.
+
+ - name: last_touch_revenue_impact.landing_page
+ description: >
+ Revenue attributed to this touchpoint as last touch for the landing page dimension.
+
+ - name: last_touch_revenue_impact.ad
+ description: >
+ Revenue attributed to this touchpoint as last touch for the ad dimension.
+
+ - name: last_touch_revenue_impact.campaign
+ description: >
+ Revenue attributed to this touchpoint as last touch for the campaign dimension.
+
+ - name: last_touch_revenue_impact.ad_group
+ description: >
+ Revenue attributed to this touchpoint as last touch for the ad group dimension.
+
+ - name: last_touch_revenue_impact.email_sms
+ description: >
+ Revenue attributed to this touchpoint as last touch for the email/SMS dimension.
+
+ - name: linear_revenue_impact
+ description: >
+ Struct containing revenue attributed to this touchpoint using linear attribution for each dimension.
+
+ - name: linear_revenue_impact.marketing_channel
+ description: >
+ Revenue attributed to this touchpoint using linear model for the marketing channel dimension.
+
+ - name: linear_revenue_impact.landing_page
+ description: >
+ Revenue attributed to this touchpoint using linear model for the landing page dimension.
+
+ - name: linear_revenue_impact.ad
+ description: >
+ Revenue attributed to this touchpoint using linear model for the ad dimension.
+
+ - name: linear_revenue_impact.campaign
+ description: >
+ Revenue attributed to this touchpoint using linear model for the campaign dimension.
+
+ - name: linear_revenue_impact.ad_group
+ description: >
+ Revenue attributed to this touchpoint using linear model for the ad group dimension.
+
+ - name: linear_revenue_impact.email_sms
+ description: >
+ Revenue attributed to this touchpoint using linear model for the email/SMS dimension.
+
+ - name: first_touch_conversion_impact
+ description: >
+ Struct containing conversion (1 or 0) attributed to this touchpoint as first touch for each dimension.
+
+ - name: last_touch_conversion_impact
+ description: >
+ Struct containing conversion (1 or 0) attributed to this touchpoint as last touch for each dimension.
+
+ - name: linear_conversion_impact
+ description: >
+ Struct containing conversion credit (fractional) attributed to this touchpoint using linear model for each dimension.
+
+ - name: attribution_metadata
+ description: >
+ Struct containing UTM parameters and event metadata for attribution tracking.
+
+ - name: attribution_metadata.event_utm_source
+ description: >
+ UTM source parameter from the event for attribution analysis.
+
+ - name: attribution_metadata.event_utm_medium
+ description: >
+ UTM medium parameter from the event for channel grouping.
+
+ - name: attribution_metadata.event_utm_campaign
+ description: >
+ UTM campaign parameter from the event for campaign attribution.
+
+ - name: attribution_metadata.event_utm_content
+ description: >
+ UTM content parameter from the event for A/B testing tracking.
+
+ - name: attribution_metadata.event_utm_term
+ description: >
+ UTM term parameter from the event for paid search keyword tracking.
+
+ - name: attribution_metadata.event_referrer_domain
+ description: >
+ Referrer domain from the event for traffic source analysis.
+
+ - name: attribution_metadata.sm_event_page_category
+ description: >
+ Page category classification for the event (product, collection, checkout, etc.).
+
+```
+
+## Example Queries
+
+### Revenue by Marketing Channel (First Touch)
+
+```sql
+SELECT
+ dimension_value.marketing_channel,
+ SUM(first_touch_revenue_impact.marketing_channel) as first_touch_revenue
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND first_touch_revenue_impact.marketing_channel > 0
+GROUP BY 1
+ORDER BY 2 DESC
+```
+
+### Compare Attribution Models for a Single Order
+
+```sql
+SELECT
+ purchase_order_id,
+ dimension_value.marketing_channel,
+ event_local_datetime,
+ linear_revenue_impact.marketing_channel as linear_revenue,
+ first_touch_revenue_impact.marketing_channel as first_touch_revenue,
+ last_touch_revenue_impact.marketing_channel as last_touch_revenue,
+ purchase_order_revenue
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND purchase_order_id = 'ORDER_ID_HERE'
+ AND dimension_value.marketing_channel IS NOT NULL
+ORDER BY event_local_datetime
+```
+
+### Days to Conversion Analysis
+
+```sql
+SELECT
+ purchase_journey_type,
+ AVG(days_to_conversion.marketing_channel) as avg_days_to_conversion,
+ COUNT(DISTINCT purchase_order_id) as journeys
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND sm_event_name = 'purchase'
+ AND days_to_conversion.marketing_channel IS NOT NULL
+GROUP BY 1
+ORDER BY 2
+```
+
+## Key Behaviors
+
+### Email/SMS Attribution Rules
+
+- **First Touch**: Email/SMS touches are excluded (can't be the first touch)
+- **Linear**: Email/SMS touches are excluded from linear attribution
+- **Last Touch**: Email/SMS can receive last touch attribution for configured customers
+
+### Brand Campaign Handling
+
+Brand campaigns appear in data but receive zero attribution to prevent brand search from inflating metrics.
+
+### Session-Based Deduplication
+
+Linear attribution uses `is_first_occurrence_*` flags to ensure unique contributions per session, preventing the same channel from being counted multiple times within a session.
+
+## Related Resources
+
+
+
+ Daily aggregated attribution metrics at ad, campaign, and channel levels
+
+
+ Complete guide to all MTA data models
+
+
+ Understanding unattributed metrics and channel rollups
+
+
diff --git a/data-activation/data-tables/sm_experimental/rpt_ad_attribution_performance_daily.mdx b/data-activation/data-tables/sm_experimental/rpt_ad_attribution_performance_daily.mdx
new file mode 100644
index 0000000..84b6b68
--- /dev/null
+++ b/data-activation/data-tables/sm_experimental/rpt_ad_attribution_performance_daily.mdx
@@ -0,0 +1,234 @@
+---
+title: 'rpt_ad_attribution_performance_daily'
+description: 'Daily ad performance with waterfall MTA attribution at ad, ad group, campaign, and channel levels.'
+icon: "table"
+---
+
+This model combines ad-level performance data with multi-touch attribution metrics using a waterfall hierarchy that ensures each dollar flows to the most granular level available.
+
+## Waterfall Attribution Hierarchy
+
+The model implements a true waterfall where attribution flows to the most specific level with data:
+
+| Level | Description | ID Populated |
+|-------|-------------|--------------|
+| `ad_level` | Most granular—individual ad performance | `ad_id` present |
+| `ad_group_level` | Ad group aggregation when no ad_id | `ad_group_id` present, `ad_id` null |
+| `campaign_level` | Campaign aggregation when no ad_group_id | `ad_campaign_id` present, both above null |
+| `channel_level` | Channel-only metrics (unattributed remainder) | All IDs null |
+
+
+Brand campaigns appear in data with spend, impressions, and clicks, but receive **zero attribution** to prevent inflating brand impact metrics.
+
+
+## Key Columns
+
+```yaml
+version: 2
+
+models:
+ - name: rpt_ad_attribution_performance_daily
+ description: >
+ Daily ad performance with waterfall MTA attribution. Grain: One row per sm_store_id + date + source_system + waterfall_level + ad hierarchy.
+ Date field: date. Critical filters: waterfall_level for aggregation granularity; ad_campaign_tactic for brand exclusion.
+ columns:
+ - name: sm_store_id
+ description: >
+ SourceMedium store identifier (brand/workspace).
+
+ - name: date
+ description: >
+ Calendar date for daily aggregation of performance and attribution metrics.
+
+ - name: source_system
+ description: >
+ Ad platform emitting performance data (facebook, google_ads, tiktok, amazon_ads, pinterest, snapchat, microsoft_ads, impact, refersion, etc.).
+
+ - name: waterfall_level
+ description: >
+ Level in the waterfall hierarchy: ad_level, ad_group_level, campaign_level, or channel_level. Use to filter or aggregate at the appropriate granularity.
+
+ - name: sm_channel
+ description: >
+ Marketing channel classification (e.g., 'Meta', 'Google', 'Impact', 'Amazon').
+
+ - name: ad_id
+ description: >
+ Ad-level identifier; populated only for ad_level waterfall rows, null for higher aggregation levels.
+
+ - name: ad_name
+ description: >
+ Ad name from the platform; available for ad_level rows.
+
+ - name: ad_group_id
+ description: >
+ Ad group identifier; populated for ad_group_level and ad_level rows, null for campaign/channel levels.
+
+ - name: ad_group_name
+ description: >
+ Ad group name from the platform; available for ad_group_level and ad_level rows.
+
+ - name: ad_campaign_id
+ description: >
+ Campaign identifier; populated for campaign_level, ad_group_level, and ad_level rows, null for channel_level.
+
+ - name: ad_campaign_name
+ description: >
+ Campaign name from the platform; available for campaign_level and more granular rows.
+
+ - name: ad_campaign_type
+ description: >
+ Campaign type classification from the platform (e.g., search, display, shopping, video).
+
+ - name: ad_campaign_tactic
+ description: >
+ Campaign tactic classification: Prospecting, Retargeting, Retention, Brand, Affiliate, or Automatic Targeting. Brand campaigns receive zero attribution.
+
+ - name: ad_creative_title
+ description: >
+ Ad creative title text for ad-level identification and creative analysis.
+
+ - name: ad_creative_image_url
+ description: >
+ URL to the ad creative image for visual reference and creative analysis.
+
+ - name: ad_platform_campaign_objective
+ description: >
+ Campaign objective set in the ad platform (e.g., conversions, traffic, awareness).
+
+ - name: ad_spend
+ description: >
+ Total advertising spend for the day at the appropriate waterfall level aggregation.
+
+ - name: ad_clicks
+ description: >
+ Total ad clicks for the day at the appropriate waterfall level aggregation.
+
+ - name: ad_impressions
+ description: >
+ Total ad impressions for the day at the appropriate waterfall level aggregation.
+
+ - name: ad_platform_reported_conversions
+ description: >
+ Platform-reported conversion count; may differ from attribution conversions due to tracking methodology.
+
+ - name: ad_platform_reported_revenue
+ description: >
+ Platform-reported revenue; may differ from attribution revenue due to tracking methodology and attribution windows.
+
+ - name: sm_first_touch_revenue
+ description: >
+ Revenue attributed to first valid non-brand touchpoint in the customer journey; excludes brand campaigns.
+
+ - name: sm_last_touch_revenue
+ description: >
+ Revenue attributed to last valid touchpoint before purchase; excludes brand campaigns and applies email/sms rules.
+
+ - name: sm_linear_revenue
+ description: >
+ Revenue attributed using linear model distributing credit evenly across valid touchpoints in the customer journey.
+
+ - name: sm_first_touch_conversions
+ description: >
+ Conversion count attributed to first valid non-brand touchpoint; fractional conversions possible for shared attribution.
+
+ - name: sm_last_touch_conversions
+ description: >
+ Conversion count attributed to last valid touchpoint before purchase; fractional conversions possible for shared attribution.
+
+ - name: sm_linear_conversions
+ description: >
+ Conversion count attributed using linear model distributing credit evenly across valid touchpoints; fractional values.
+
+```
+
+## Example Queries
+
+### Campaign ROAS by Attribution Model
+
+```sql
+SELECT
+ ad_campaign_name,
+ SUM(ad_spend) as total_spend,
+ SUM(sm_last_touch_revenue) as last_touch_revenue,
+ SUM(sm_first_touch_revenue) as first_touch_revenue,
+ SUM(sm_linear_revenue) as linear_revenue,
+ SAFE_DIVIDE(SUM(sm_last_touch_revenue), SUM(ad_spend)) as last_touch_roas,
+ SAFE_DIVIDE(SUM(sm_linear_revenue), SUM(ad_spend)) as linear_roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND waterfall_level = 'campaign_level'
+ AND ad_campaign_tactic != 'brand'
+GROUP BY 1
+ORDER BY total_spend DESC
+```
+
+### Ad-Level Performance with Attribution
+
+```sql
+SELECT
+ source_system,
+ ad_campaign_name,
+ ad_name,
+ SUM(ad_spend) as spend,
+ SUM(ad_clicks) as clicks,
+ SUM(sm_last_touch_conversions) as attributed_conversions,
+ SUM(sm_last_touch_revenue) as attributed_revenue,
+ SAFE_DIVIDE(SUM(sm_last_touch_revenue), SUM(ad_spend)) as roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
+ AND waterfall_level = 'ad_level'
+GROUP BY 1, 2, 3
+HAVING spend > 100
+ORDER BY attributed_revenue DESC
+LIMIT 20
+```
+
+### Channel Performance Summary
+
+```sql
+SELECT
+ sm_channel,
+ SUM(ad_spend) as total_spend,
+ SUM(sm_first_touch_revenue) as first_touch_revenue,
+ SUM(sm_last_touch_revenue) as last_touch_revenue,
+ SUM(sm_linear_revenue) as linear_revenue
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN '2024-01-01' AND '2024-12-31'
+GROUP BY 1
+ORDER BY total_spend DESC
+```
+
+## Key Behaviors
+
+### Brand Campaign Handling
+
+Brand campaigns (where `ad_campaign_tactic = 'brand'`) appear in the data with full performance metrics (spend, clicks, impressions) but receive **zero attribution** across all models (first touch, last touch, linear). This prevents brand search from receiving credit that belongs to non-brand touchpoints.
+
+### Channel-Level Unattributed Metrics
+
+Channel-level rows (`waterfall_level = 'channel_level'`) contain only unattributed metrics—spend and performance that couldn't be matched to a specific ad, ad group, or campaign. This prevents double-counting while maintaining complete visibility into marketing spend.
+
+### Amazon and TikTok Shop
+
+Amazon and TikTok Shop channels cannot have SourceMedium attribution since these platforms don't share customer-level conversion data. Platform-reported metrics are available, but `sm_*` attribution columns will be zero.
+
+## Related Resources
+
+
+
+ Complete guide to all MTA data models including purchase journeys
+
+
+ Understanding unattributed metrics and channel rollups
+
+
+ Base ad performance table without attribution (sm_transformed_v2)
+
+
diff --git a/data-activation/data-tables/sm_metadata/dim_data_dictionary.mdx b/data-activation/data-tables/sm_metadata/dim_data_dictionary.mdx
new file mode 100644
index 0000000..c581da4
--- /dev/null
+++ b/data-activation/data-tables/sm_metadata/dim_data_dictionary.mdx
@@ -0,0 +1,62 @@
+---
+title: 'dim_data_dictionary'
+description: 'Metadata table for table availability, freshness, and column coverage used by SourceMedium.'
+icon: "table"
+---
+
+```yaml
+version: 2
+
+models:
+ - name: dim_data_dictionary
+ description: >
+ Metadata table used for table availability, data freshness, and column coverage hints. It is queried by SourceMedium systems to determine which tables are present and whether they have recent data. Grain varies by row: table-level availability fields can appear alongside column-level coverage fields.
+ columns:
+ - name: dataset_name
+ description: >
+ Dataset containing the table (e.g., 'sm_transformed_v2').
+
+ - name: table_name
+ description: >
+ Table name (e.g., 'obt_orders').
+
+ - name: table_has_data
+ description: >
+ Boolean indicating whether the table has data for at least one store.
+
+ - name: table_has_fresh_data_14d
+ description: >
+ Boolean indicating whether the table has had data in the last 14 days for at least one store.
+
+ - name: table_last_data_date
+ description: >
+ Most recent date with data for the table (best-effort).
+
+ - name: table_description
+ description: >
+ Human-readable table description, when available.
+
+ - name: column_name
+ description: >
+ Column name within the table, when the row contains column-level metadata.
+
+ - name: column_null_percentage
+ description: >
+ Percent of rows where the column is null (0–100), when available.
+
+ - name: column_distinct_count
+ description: >
+ Number of distinct values observed for the column (best-effort), when available.
+
+ - name: categorical_value_distribution
+ description: >
+ Array of structs describing top categorical values and their distribution, when available.
+
+ - name: categorical_value_distribution.value
+ description: >
+ Categorical value.
+
+ - name: categorical_value_distribution.pct
+ description: >
+ Percent share for the categorical value.
+```
diff --git a/data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog.mdx b/data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog.mdx
new file mode 100644
index 0000000..b4b278c
--- /dev/null
+++ b/data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog.mdx
@@ -0,0 +1,356 @@
+---
+title: 'dim_semantic_metric_catalog'
+description: 'Self-documenting catalog of all semantic layer metrics with their calculations, categories, and dependencies.'
+icon: "book-open"
+---
+
+The `dim_semantic_metric_catalog` table provides a comprehensive, always-current reference for all metrics available in the SourceMedium semantic layer. Unlike static documentation, this table is dynamically generated from the actual metric definitions, ensuring it always reflects the current state of your metrics.
+
+
+This is the **source of truth** for metric definitions. The catalog currently contains 180+ metrics. Query this table to discover available metrics, understand their calculations, and find the right metric for your analysis.
+
+
+## Use Cases
+
+- **Metric Discovery**: Find all available metrics and filter by category or type
+- **Understanding Calculations**: See exactly how each metric is calculated
+- **Dependency Tracking**: Identify which metrics depend on other metrics
+- **Alias Resolution**: Map abbreviated metric names (like `aov`) to their full descriptive names
+- **Documentation**: Generate metric documentation for your team
+
+## Schema
+
+```yaml
+version: 2
+
+models:
+ - name: dim_semantic_metric_catalog
+ description: >
+ A clean, user-friendly catalog of all semantic layer metrics with parsed configurations.
+ Dynamically generated from dbt metric definitions at build time.
+ columns:
+ - name: metric_name
+ description: >
+ Unique identifier for the metric (e.g., 'order_net_revenue', 'average_order_value_net').
+ This is the name you use when querying the semantic layer.
+
+ - name: metric_label
+ description: >
+ Human-readable display name (e.g., "Order Net Revenue", "Average Order Value (AOV) - Net").
+ Use this for dashboard labels and reports.
+
+ - name: metric_description
+ description: >
+ Detailed explanation of what the metric measures and how it should be interpreted.
+
+ - name: metric_type
+ description: >
+ Type of metric calculation. One of:
+ - `simple`: Direct aggregation of a measure (SUM, COUNT)
+ - `ratio`: Division of two metrics (e.g., revenue / orders = AOV)
+ - `derived`: Calculation combining multiple metrics with custom expressions
+ - `cumulative`: Running totals over time (MTD, QTD, YTD, trailing windows)
+
+ - name: metric_category
+ description: >
+ Business category for grouping related metrics:
+ - `revenue`: AOV, revenue totals, profit metrics
+ - `customer`: Customer counts, acquisition, retention metrics
+ - `conversion`: Conversion rates, funnel metrics
+ - `marketing`: Ad spend, efficiency ratios (MER, CAC, CPO, ROAS)
+ - `product`: Product/SKU counts, inventory metrics
+ - `cumulative`: Time-based cumulative metrics (MTD, QTD, YTD)
+ - `period_comparison`: MoM, YoY comparison metrics
+ - `other`: Uncategorized metrics
+
+ - name: calculation
+ description: >
+ Readable calculation formula showing how the metric is computed:
+ - Simple: "SUM(order_net_revenue) WHERE [filter applied]", "SUM(valid_order_count)"
+ - Ratio: "order_net_revenue / order_count"
+ - Derived: Custom expression combining metrics
+ - Cumulative: "CUMULATIVE_SUM(order_net_revenue)"
+
+ - name: has_filter
+ description: >
+ Boolean flag indicating whether the metric has a filter condition applied.
+ TRUE if the metric filters data (e.g., only valid orders, only new customers).
+
+ - name: filter_condition
+ description: >
+ The actual filter condition applied to the metric, if any.
+ NULL if no filter is applied.
+
+ - name: metric_time_grains
+ description: >
+ Available time granularities for this metric.
+ Default: "day, week, month, quarter, year"
+
+ - name: cumulative_settings
+ description: >
+ Configuration for cumulative metrics:
+ - "month", "quarter", "year" for grain-to-date (MTD, QTD, YTD)
+ - "30 day", "90 day", "365 day" for trailing windows
+ - "all_time" for unbounded cumulative from the beginning
+ - NULL for non-cumulative metrics
+
+ - name: semantic_model_name
+ description: >
+ The semantic model that defines this metric's measures.
+ Common values: 'orders', 'customers', 'ad_performance', 'funnel_events', 'products', 'executive_summary'.
+ Special values: 'Multiple' (uses multiple models), 'Derived' (uses other metrics), 'None'.
+
+ - name: underlying_model
+ description: >
+ The dbt model(s) containing the actual data for this metric.
+ Examples: 'obt_orders', 'obt_customers', 'rpt_ad_performance_daily'.
+ Can be 'Multiple models' for metrics spanning multiple data sources.
+
+ - name: dependent_metrics
+ description: >
+ Comma-separated list of metrics this metric depends on.
+ Populated for ratio and derived metrics.
+ Example: "total_ad_clicks, total_ad_impressions" for click_through_rate.
+
+ - name: dependent_metric_count
+ description: >
+ Number of metrics this metric depends on.
+ 0 for simple metrics, 2 for ratio metrics, varies for derived metrics.
+
+ - name: is_abbreviation
+ description: >
+ Boolean flag indicating if this is an abbreviated/alias metric name.
+ TRUE for metrics like 'aov', 'mer', 'cac' that have full descriptive equivalents.
+ Use the full name for new implementations.
+
+ - name: preferred_metric_name
+ description: >
+ For abbreviation metrics, the full descriptive metric name to use instead.
+ Example: 'aov' -> 'average_order_value_net', 'mer' -> 'marketing_efficiency_ratio'.
+ NULL for primary metrics.
+
+ - name: abbreviations_list
+ description: >
+ For primary metrics, a comma-separated list of abbreviations that map to this metric.
+ Example: 'average_order_value_net' has abbreviations 'aov, aov_net_revenue'.
+ NULL for abbreviation metrics.
+
+ - name: catalog_updated_at
+ description: >
+ Timestamp when this catalog entry was last refreshed.
+ All rows share the same timestamp from the most recent build.
+```
+
+## Example Queries
+
+### Find All Revenue Metrics
+
+```sql
+SELECT
+ metric_name,
+ metric_label,
+ metric_type,
+ calculation
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_category = 'revenue'
+ORDER BY metric_name
+```
+
+### Discover Marketing Efficiency Metrics
+
+```sql
+SELECT
+ metric_name,
+ metric_description,
+ calculation,
+ dependent_metrics
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_category = 'marketing'
+ AND metric_type = 'ratio'
+ORDER BY metric_name
+```
+
+### Resolve an Abbreviated Metric Name
+
+```sql
+-- What is "aov" actually measuring?
+SELECT
+ metric_name,
+ preferred_metric_name,
+ metric_description,
+ calculation
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_name = 'aov'
+```
+
+### Find All Abbreviations for a Metric
+
+```sql
+-- What abbreviations exist for average_order_value_net?
+SELECT
+ metric_name,
+ abbreviations_list
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_name = 'average_order_value_net'
+ OR preferred_metric_name = 'average_order_value_net'
+```
+
+### List All Cumulative (MTD/QTD/YTD) Metrics
+
+```sql
+SELECT
+ metric_name,
+ metric_label,
+ cumulative_settings,
+ calculation
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_type = 'cumulative'
+ORDER BY cumulative_settings, metric_name
+```
+
+### Find Metrics by Underlying Data Source
+
+```sql
+-- What metrics can I get from the orders data?
+SELECT
+ metric_name,
+ metric_type,
+ metric_category
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE semantic_model_name = 'orders'
+ORDER BY metric_category, metric_name
+```
+
+### Explore Metric Dependencies
+
+```sql
+-- Which metrics depend on order_net_revenue?
+SELECT
+ metric_name,
+ metric_type,
+ dependent_metrics
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE dependent_metrics LIKE '%order_net_revenue%'
+ORDER BY metric_name
+```
+
+### Get Canonical Metric Names (Resolving Aliases)
+
+```sql
+-- Always use the preferred (non-abbreviated) metric name
+SELECT
+ metric_name AS requested_name,
+ COALESCE(preferred_metric_name, metric_name) AS canonical_name,
+ metric_description
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE metric_name IN ('aov', 'mer', 'cac', 'average_order_value_net')
+```
+
+## Metric Types Explained
+
+
+
+ Direct aggregations of a single measure. These are the building blocks for other metric types.
+
+ **Examples:**
+ - `order_net_revenue` = SUM(order_net_revenue)
+ - `order_count` = SUM(valid_order_count)
+ - `new_customers` = SUM(customer_count) with filter
+
+ **Calculation column shows:** `SUM(measure_name)` or `SUM(measure_name) WHERE [filter applied]`
+
+
+
+ Division of two metrics, typically used for averages and rates.
+
+ **Examples:**
+ - `average_order_value_net` = order_net_revenue / order_count
+ - `customer_acquisition_cost` = total_ad_spend / new_customer_order_count
+ - `click_through_rate` = total_ad_clicks / total_ad_impressions
+
+ **Calculation column shows:** `numerator_metric / denominator_metric`
+
+
+
+ Custom calculations combining multiple metrics with expressions.
+
+ **Examples:**
+ - `cost_per_thousand_impressions` = total_ad_spend * 1000 / total_ad_impressions
+ - `gross_margin` = gross_profit / order_net_revenue
+
+ **Calculation pattern:** Custom SQL expression
+
+
+
+ Running totals that accumulate over time periods.
+
+ **Grain-to-date:**
+ - `mtd_net_revenue` = Month-to-date net revenue (resets each month)
+ - `qtd_net_revenue` = Quarter-to-date net revenue
+ - `ytd_net_revenue` = Year-to-date net revenue
+
+ **Trailing windows:**
+ - `trailing_30d_revenue` = Revenue for the last 30 days
+ - `trailing_90d_revenue` = Revenue for the last 90 days
+
+ **Calculation column shows:** `CUMULATIVE_SUM(measure_name)`
+
+
+
+## Metric Categories
+
+| Category | Description | Example Metrics |
+|----------|-------------|-----------------|
+| `revenue` | Revenue, profit, and average order value metrics | `order_net_revenue`, `average_order_value_net`, `gross_profit` |
+| `customer` | Customer counts and acquisition metrics | `new_customers`, `new_customer_order_count`, `total_customers` |
+| `conversion` | Conversion rates and funnel metrics | `conversion_rate`, `add_to_cart_rate`, `checkout_completion_rate` |
+| `marketing` | Ad spend and efficiency metrics | `total_ad_spend`, `marketing_efficiency_ratio`, `cost_per_click` |
+| `product` | Product and inventory metrics | `total_products`, `total_skus`, `product_page_views` |
+| `cumulative` | Time-based running totals | `mtd_net_revenue`, `ytd_order_count`, `trailing_30d_revenue` |
+| `period_comparison` | Period-over-period comparisons | `order_count_mom_change`, `order_count_yoy_change` |
+
+## Common Aliases Reference
+
+The semantic layer supports abbreviated metric names for convenience. Always use the full descriptive name for new implementations.
+
+| Alias | Preferred Metric | Description |
+|-------|------------------|-------------|
+| `aov` | `average_order_value_net` | Average Order Value |
+| `mer` | `marketing_efficiency_ratio` | Marketing Efficiency Ratio (blended ROAS) |
+| `cac` | `customer_acquisition_cost` | Customer Acquisition Cost |
+| `cpc` | `cost_per_click` | Cost Per Click |
+| `cpm` | `cost_per_thousand_impressions` | Cost Per Mille (thousand impressions) |
+| `cpo` | `cost_per_order` | Cost Per Order |
+| `roas` | `return_on_ad_spend` | Return on Ad Spend |
+| `ctr` | `click_through_rate` | Click-Through Rate |
+| `cvr` | `conversion_rate` | Conversion Rate |
+| `cpa` | `customer_acquisition_cost` | Cost Per Acquisition (same as CAC) |
+
+
+Query the catalog with `WHERE is_abbreviation = true` to see all available aliases and their preferred metric names.
+
+
+## Best Practices
+
+
+
+ For new dashboards and queries, always use the full descriptive metric name (e.g., `average_order_value_net` instead of `aov`). This improves readability and maintainability.
+
+
+
+ When filtering metrics, check the `dependent_metrics` column to understand what underlying data will be affected. Ratio and derived metrics may behave unexpectedly with certain dimension filters.
+
+
+
+ When combining metrics in a query, prefer metrics from the same `semantic_model_name` for consistent dimension availability. Mixing metrics from different semantic models may limit available dimensions.
+
+
+
+ For MTD, QTD, or YTD reporting, use the pre-built cumulative metrics instead of writing custom window functions. They handle edge cases like partial periods correctly.
+
+
+
+## Related Resources
+
+- [Metric Definitions](/onboarding/data-docs/metrics) - Curated list of key metrics with descriptions
+- [dim_data_dictionary](/data-activation/data-tables/sm_metadata/dim_data_dictionary) - Table availability and column metadata
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_customer_addresses.mdx b/data-activation/data-tables/sm_transformed_v2/dim_customer_addresses.mdx
index ec03cb8..a6c533c 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_customer_addresses.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_customer_addresses.mdx
@@ -1,69 +1,82 @@
---
title: 'dim_customer_addresses'
-description: ''
+description: 'Customer address dimension for enriching customers and orders with normalized geo attributes.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_customer_addresses
description: >
- The dim_customer_addresses table contains dimensions associated with addresses of customers who have placed orders from a shop.
+ Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1).
columns:
- - name: smcid
+ - name: address_id
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
- - name: sm_customer_address_key
+ The unique identifier for the address.
+
+ - name: customer_address_city
description: >
- The unique address key created by SourceMedium that can be used to join address dimensions to related tables.
- tests:
- - not_null
- - unique
- - name: source_system
+ The city the customer's location is in.
+
+ - name: customer_address_country
description: >
- The e-commerce source system used to facilitate a customer's order.
- - name: sm_customer_key
+ The country the customer's location is in.
+
+ - name: customer_address_country_code
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- - name: is_default_address_for_customer
+ The two-letter code (ISO 3166-1 format) for the country of the customer's location.
+
+ - name: customer_address_province
description: >
- Whether the address is the default address for the customer.
- - name: address_1
+ The province, state, or district code of the customer's location.
+
+ - name: customer_address_province_code
description: >
- The customer's street address.
- - name: address_2
+ The province, state, or district code (ISO 3166-2 alpha-2 format) of the customer's location.
+
+ - name: customer_address_latitude
description: >
- The optional second line of the customer's street address.
- - name: city
+ The latitude coordinate of the customer's location.
+
+ - name: customer_address_longitude
description: >
- The city the customer's location is in.
- - name: country
+ The longitude coordinate of the customer's location.
+
+ - name: customer_address_zip_code
description: >
- The country the customer's location is in.
- - name: country_code
+ The postal code of the customer's location.
+
+ - name: customer_id
description: >
- The two-letter code (ISO 3166-1 format) for the country of the customer's location.
- - name: latitude
+ Platform-specific customer identifier from the source system. Links to the customer who owns this address.
+
+ - name: customer_street_address
description: >
- The latitude coordinate of the customer's location.
- - name: longitude
+ The customer's street address.
+
+ - name: is_default_for_customer
description: >
- The longitude coordinate of the customer's location.
- - name: province
+ Whether the address is the default address for the customer.
+
+ - name: is_default_address_for_customer
description: >
- The province, state, or district code of the customer's location.
- - name: province_code
+ Boolean indicating whether this address is the default/primary address for the customer. Used to identify the customer's preferred address for shipping and billing.
+
+ - name: sm_customer_address_key
description: >
- The province, state, or district code (ISO 3166-2 alpha-2 format) of the customer's location.
- - name: zip_code
+ The unique address key created by SourceMedium that can be used to join address dimensions to related tables.
+
+ - name: sm_customer_key
description: >
- The postal code of the customer's location.
- - name: _synced_at
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_customers.mdx b/data-activation/data-tables/sm_transformed_v2/dim_customers.mdx
index 14a04e6..a9e0d41 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_customers.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_customers.mdx
@@ -1,72 +1,51 @@
---
title: 'dim_customers'
-description: ''
+description: 'Customer dimension with stable keys and profile attributes for joining and segmentation.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_customers
description: >
- The dim_customers table is a dimensional table containing customer information derived from e-commerce transactions.
+ Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many).
columns:
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: sm_customer_key
- description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
- - unique
-
- - name: source_system
- description: >
- The e-commerce source system used to facilitate a customer's order.
- tests:
- - not_null
-
- - name: customer_id
- description: >
- The ID of the customer who placed the order.
- tests:
- - not_null
-
- name: customer_created_at
description: >
- The autogenerated date and time when the customer was created.
-
- - name: customer_updated_at
- description: >
- The autogenerated date and time when the customer was last modified.
+ UTC timestamp when the customer was created.
- name: customer_email
description: >
- The customer's email.
+ Customer email address (PII); see customer_email_hashed for privacy‑safe matching.
- name: customer_email_hashed
description: >
- The customer's email hashed.
+ SHA-256 hash of customer email address. Used for privacy-safe customer matching and analytics across systems without exposing PII.
- name: customer_first_name
description: >
- The customer's first name.
+ Customer's first name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.
+
+ - name: customer_id
+ description: >
+ The ID of the customer who placed the order.
- name: customer_last_name
description: >
- The customer's last name.
+ Customer's last name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.
+
+ - name: customer_phone_number
+ description: >
+ Customer's phone number in platform-provided format (varies by source_system). May be NULL if not collected; formatting and country codes not standardized.
- name: customer_tags_csv
description: >
- An aggregated list of all tags associated with a customer.
+ Comma-separated list of all tags associated with a customer. Use for simple filtering; beware that individual tag values may contain commas.
- - name: customer_tags_array
+ - name: customer_updated_at
description: >
- An array of all tags associated with a customer.
+ UTC timestamp when the customer was last modified.
- name: has_customer_consented_to_marketing
description: >
@@ -76,7 +55,16 @@ models:
description: >
Whether the customer's email has been verified.
- - name: _synced_at
+ - name: sm_customer_key
+ description: >
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.
+
+ - name: sm_store_id
description: >
- The date and time when SourceMedium last successfully synced the row of data.
-```
\ No newline at end of file
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
+ description: >
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_order_discounts.mdx b/data-activation/data-tables/sm_transformed_v2/dim_order_discounts.mdx
index e747cda..f599fbc 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_order_discounts.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_order_discounts.mdx
@@ -1,80 +1,66 @@
---
title: 'dim_order_discounts'
-description: ''
+description: 'Order discount dimension with discount types, codes, and values.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_order_discounts
description: >
- The dim_order_discounts table is a dimensional table containing information about discounts that have been applied to orders and order lines.
+ Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1).
columns:
- - name: smcid
+ - name: discount_code
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ The case-insensitive discount code that customers use at checkout.
- - name: sm_order_discount_key
+ - name: discount_index
description: >
- The unique discount key created by SourceMedium that can be used to join discount dimensions to related tables.
- tests:
- - not_null
- - unique
+ An ordered index that can be used to identify the discount application and indicate the precedence of the discount application for calculations.
- - name: sm_order_line_key
+ - name: discount_line_entity
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
- tests:
- - not_null
+ The entity that the discount is applied to, such as an order line or a shipping line.
- - name: sm_order_key
+ - name: discount_type
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
+ The type of discount, such as an automatic discount, a discount code, or a manual discount.
- - name: source_system
+ - name: discounts
description: >
- The e-commerce source system used to facilitate an order.
+ The amount of the discount applied to the discount entity.
- - name: order_line_id
+ - name: order_currency_code
description: >
- The ID of the order line.
+ The three-letter code (ISO 4217 format) for the currency used for the tender transaction.
- name: order_id
description: >
- The ID of the order.
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: discount_index
+ - name: order_line_id
description: >
- An ordered index that can be used to identify the discount application and indicate the precedence of the discount application for calculations.
+ The ID of the order line.
- - name: discount_code
+ - name: sm_order_discount_key
description: >
- The case-insensitive discount code that customers use at checkout.
+ The unique discount key created by SourceMedium that can be used to join discount dimensions to related tables.
- - name: discount_type
+ - name: sm_order_key
description: >
- The type of discount, such as an automatic discount, a discount code, or a manual discount.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: discount_line_entity
+ - name: sm_order_line_key
description: >
- The entity that the discount is applied to, such as an order line or a shipping line.
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: discounts
+ - name: sm_store_id
description: >
- The amount of the discount applied to the discount entity.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: order_currency_code
+ - name: source_system
description: >
- The three-letter code (ISO 4217 format) for the currency used for the tender transaction.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- - name: _synced_at
- description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_order_lines.mdx b/data-activation/data-tables/sm_transformed_v2/dim_order_lines.mdx
index 5b9791a..c596564 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_order_lines.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_order_lines.mdx
@@ -1,55 +1,39 @@
---
title: 'dim_order_lines'
-description: ''
+description: 'Order line dimension for product-level attributes at line grain.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_order_lines
description: >
- The dim_order_lines is a dimensional table containing order line information derived from e-commerce transactions.
-
+ Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1).
columns:
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: sm_order_line_key
+ - name: order_line_id
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
- tests:
- - not_null
- - unique
+ The ID of the order line.
- - name: sm_order_key
+ - name: order_line_price
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
+ The price of a single unit of the product at the time of purchase (before line-level discounts). Multiply by order_line_quantity to get total line revenue.
- - name: sm_product_key
+ - name: order_line_product_title
description: >
- The unique product key created by SourceMedium that can be used to join product dimensions to related tables.
- tests:
- - not_null
+ The title of the product variant that the order line represents.
- - name: sm_product_variant_key
+ - name: order_line_product_variant_title
description: >
- The unique product variant key created by SourceMedium that can be used to join product variant dimensions to related tables.
- tests:
- - not_null
+ The title of the product variant that the order line represents.
- - name: source_system
+ - name: order_line_quantity
description: >
- The e-commerce source system used to facilitate a customer's order.
+ The number of units of the product variant ordered in this line item. Used to calculate total line revenue (order_line_price * order_line_quantity).
- - name: order_line_id
+ - name: product_id
description: >
- The ID of the order line.
+ Platform-specific product identifier from the source system. Links to the parent product that this line item's variant belongs to.
- name: product_variant_id
description: >
@@ -59,15 +43,28 @@ models:
description: >
The stock keeping unit (SKU) of the product variant.
- - name: order_line_product_title
+ - name: sm_order_key
description: >
- The title of the product variant that the order line represents.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: order_line_product_variant_title
+ - name: sm_order_line_key
description: >
- The title of the product variant that the order line represents.
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
+
+ - name: sm_product_key
+ description: >
+ Stable SourceMedium join key for products to related tables.
+
+ - name: sm_product_variant_key
+ description: >
+ Stable SourceMedium join key for product variants to related tables.
- - name: order_cart_quantity
+ - name: sm_store_id
description: >
- The number of items that were originally purchased in an order.
-```
\ No newline at end of file
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
+ description: >
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines.mdx b/data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines.mdx
index e683c2c..5c8e2af 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines.mdx
@@ -1,51 +1,50 @@
---
title: 'dim_order_shipping_lines'
-description: ''
+description: 'Order shipping line dimension for shipping method and cost details at line-level.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_order_shipping_lines
description: >
- The dim_order_shipping_lines table contains dimensions associated with shipping lines applied to orders.
+ Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1).
columns:
- - name: smcid
+ - name: order_id
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
- - name: sm_shipping_line_key
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
+
+ - name: order_shipping_line_id
description: >
- The unique shipping line key created by SourceMedium that can be used to join shipping line dimensions to related tables.
- tests:
- - not_null
- - unique
- - name: source_system
+ The ID that represents the shipping details for a customer's order.
+
+ - name: order_shipping_line_shipping
description: >
- The e-commerce source system used to facilitate a customer's order.
- - name: sm_order_line_key
+ The shipping cost amount for this specific shipping line item. Represents the individual shipping charge when multiple shipping methods are used.
+
+ - name: order_shipping_line_title
description: >
- The unique order line item key created by SourceMedium that can be used to join order line item dimensions to related tables.
+ The title of the shipping line (e.g., 2-3 Day Shipping, Economy Shipping).
+
- name: sm_order_key
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- - name: order_shipping_line_id
- description: >
- The ID that represents the shipping details for a customer's order.
- - name: order_id
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
+
+ - name: sm_order_line_key
description: >
- The ID of the order.
- - name: shipping
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
+
+ - name: sm_shipping_line_key
description: >
- The amount the customer paid in shipping for an order.
- - name: order_shipping_line_title
+ The unique shipping line key created by SourceMedium that can be used to join shipping line dimensions to related tables.
+
+ - name: sm_store_id
description: >
- The title of the shipping line (e.g., 2-3 Day Shipping, Economy Shipping).
- - name: _synced_at
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_order_taxes.mdx b/data-activation/data-tables/sm_transformed_v2/dim_order_taxes.mdx
index 770105c..3afe8e7 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_order_taxes.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_order_taxes.mdx
@@ -1,72 +1,62 @@
---
title: 'dim_order_taxes'
-description: ''
+description: 'Order tax dimension with tax names and amounts for reconciliation and reporting.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_order_taxes
description: >
- The dim_order_taxes table is a dimensional table containing information about taxes applied to orders.
+ Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1).
columns:
- - name: smcid
+ - name: order_id
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: sm_order_tax_key
+ - name: order_line_id
description: >
- The unique order tax key created by SourceMedium that can be used to join order tax dimensions to related tables.
- tests:
- - not_null
- - unique
+ The ID of the order line.
- - name: sm_order_line_key
+ - name: order_shipping_line_id
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
+ The ID of the shipping line.
- name: sm_order_key
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: source_system
- description: >
- The e-commerce source system used to facilitate a customer's order.
-
- - name: order_line_id
+ - name: sm_order_line_key
description: >
- The ID of the order line.
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: order_shipping_line_id
+ - name: sm_order_tax_key
description: >
- The ID of the shipping line.
+ The unique order tax key created by SourceMedium that can be used to join order tax dimensions to related tables.
- - name: order_id
+ - name: sm_store_id
description: >
- The ID of the order.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: tax_line_type
+ - name: source_system
description: >
- The type of tax (e.g., state, county, excise and use, sales) applied to an order line.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- name: tax_line_entity
description: >
The line the tax applies to (e.g., shipping, order).
- - name: taxes
- description: >
- The amount of tax associated with a tax line entity, after discounts and before returns.
-
- name: tax_line_rate
description: >
The proportion of the order price that the tax represents.
- - name: _synced_at
+ - name: tax_line_type
+ description: >
+ The type of tax (e.g., state, county, excise and use, sales) applied to an order line.
+
+ - name: taxes
description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+ The amount of tax associated with a tax line entity, after discounts and before returns.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_orders.mdx b/data-activation/data-tables/sm_transformed_v2/dim_orders.mdx
index c332edd..96cf37d 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_orders.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_orders.mdx
@@ -1,226 +1,242 @@
---
title: 'dim_orders'
-description: ''
+description: 'Order dimension with stable keys and descriptive attributes for joining and exploration.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_orders
description: >
- The dim_orders table is a dimensional table containing information about orders that have been placed by customers.
+ Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1).
columns:
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: sm_order_key
+ - name: customer_device_type
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
- - unique
+ Device type derived from user agent (e.g., mobile, desktop, tablet). Coverage depends on website tracking; limited for marketplaces.
- - name: sm_customer_key
+ - name: customer_id
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
+ The ID of the customer who placed the order.
- - name: source_system
+ - name: is_price_tax_inclusive
description: >
- The e-commerce source system used to facilitate an order.
+ Whether taxes are included in the order subtotal.
- - name: order_id
+ - name: order_cancellation_reason
description: >
- The ID of the order.
+ The customer's reason for the order's cancellation.
- - name: customer_id
+ - name: order_cancelled_at
description: >
- The ID of the customer who placed the order.
+ UTC timestamp when the order was cancelled. Null if order has not been cancelled.
- - name: order_name
+ - name: order_cancelled_at_local_datetime
description: >
- A separate unique identifier for the order generated by the source system.
+ Order cancelled timestamp converted to reporting timezone (from order_cancelled_at UTC). Null if order has not been cancelled.
- - name: order_number
+ - name: order_cart_quantity
description: >
- The order's position in the shop's count of orders.
+ Total number of items (quantity across all line items) in the order cart. Sum of all order_line_quantity values for the order.
- name: order_checkout_id
description: >
The ID of the checkout that the order is associated with.
- - name: order_currency
- description: >
- The three-letter code (ISO 4217 format) for the currency used for the tender transaction.
-
- name: order_created_at
description: >
- The autogenerated date and time when the order was created.
+ UTC timestamp when the order was created.
- name: order_created_at_local_datetime
description: >
- The autogenerated date and time when the order was created, converted to the reporting timezone configured in SourceMedium.
+ Order created timestamp converted to reporting timezone (from order_created_at UTC).
- - name: order_updated_at
+ - name: order_currency_code
description: >
- The autogenerated date and time when the order was last modified.
+ Three-letter ISO 4217 currency code for the order (e.g., USD, EUR, GBP). Used for multi-currency analysis and reporting.
- - name: order_updated_at_local_datetime
+ - name: order_customer_street_address
description: >
- The autogenerated date and time when the order was last modified, converted to the reporting timezone configured in SourceMedium.
+ Customer's billing street address associated with the order. May differ from shipping address; use for billing analysis and fraud detection.
- - name: order_processed_at
+ - name: order_id
description: >
- The autogenerated date and time when the order was processed.
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: order_processed_at_local_datetime
+ - name: order_index
description: >
- The autogenerated date and time when the order was processed, converted to the reporting timezone configured in SourceMedium.
+ Ordered index identifying the sequential position of an order in a customer's order history.
- - name: order_cancelled_at
+ - name: order_index_reversed
description: >
- The autogenerated date and time when the order was cancelled.
+ Ordered index identifying the sequential position of an order in a customer's order history, in reverse order.
- - name: order_cancelled_at_local_datetime
+ - name: order_name
description: >
- The autogenerated date and time when the order was cancelled, converted to the reporting timezone configured in SourceMedium.
+ Platform-rendered name (human‑readable or platform‑specific). Not a stable join key.
- - name: order_cancellation_reason
+ - name: order_number
description: >
- The customer's reason for the order's cancellation.
+ Shop-scoped sequence number assigned by the platform. Not globally unique; pair with `sm_store_id` for scoping.
- - name: sm_order_sales_channel
+ - name: order_payment_status
description: >
- The name of the sales channel used to place an order, which is derived from the order source name, payment gateway name, and order tags.
+ Financial status of the order (e.g., paid, partially_paid, partially_refunded, authorized, pending, refunded, voided, draft). Platform‑defined.
- - name: order_source_name
+ - name: order_processed_at
description: >
- Where the order originated as reported by the source system.
+ UTC timestamp when the order was processed.
- - name: order_referring_site
+ - name: order_processed_at_local_datetime
+ description: >
+ Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.
+
+ - name: order_processing_method
+ description: >
+ The processing method used for the order (e.g., checkout, manual, express). Indicates how the order was created and processed in the source system.
+
+ - name: order_referrer_url
description: >
The URL of the site that referred the customer to the shop.
- - name: sm_order_referrer_source
+ - name: order_sequence
description: >
- A cleaned version of the website where the customer clicked a link to the shop.
+ Customer lifecycle classification: '1st_order' for new customers, 'repeat_order' for returning customers. Includes all orders (valid + invalid). Use for cohort analysis and retention reporting. See sm_valid_order_index for valid-only ordering.
- - name: sm_order_landing_page
+ - name: order_session_browser_type
description: >
- The URL for the page where the buyer landed when they entered the shop.
+ Browser type derived from user agent (e.g., chrome, safari, firefox). Coverage depends on website tracking; limited for marketplaces.
- - name: sm_order_referrer_domain
+ - name: order_session_user_agent
description: >
- The domain of the website where the customer clicked a link to the shop.
+ Raw user agent string. Used to derive customer_device_type and order_session_browser_type.
- - name: order_index
+ - name: order_shipping_city
description: >
- An ordered index that can be used to identify the sequential position of an order relative to a customer's order history.
+ The city, town, or village of the shipping address.
- - name: order_index_reversed
+ - name: order_shipping_country
+ description: >
+ The country of the shipping address.
+
+ - name: order_shipping_country_code
description: >
- An ordered index that can be used to identify the sequential position of an order relative to a customer's order history, in reverse order.
+ The two-letter code (ISO 3166-1 format) for the country of the shipping address.
- - name: order_tags_csv
+ - name: order_shipping_state
description: >
- A list of tags that the shop owner has attached to the order.
+ Province/state of the shipping address; format varies by country and platform.
- - name: order_tags_array
+ - name: order_shipping_zip_code
description: >
- A list of tags that the shop owner has attached to the order in an array format.
+ The postal code of the shipping address.
- - name: order_sequence
+ - name: source_system_sales_channel
description: >
- Whether an order is the first order or a repeat order.
+ Original source reported by the platform (e.g., Shopify sales channel/app name).
- - name: order_session_user_agent
+ - name: order_tags_csv
description: >
- The user agent of the device used by the customer to place the order.
+ Comma-separated list of tags that the shop owner has attached to the order. Use for simple filtering; beware that individual tag values may contain commas.
- - name: customer_device_type
+ - name: order_updated_at
description: >
- The type of device used by the customer to place the order, which is derived from the user agent.
+ UTC timestamp from source system when the order was last modified.
- - name: order_session_browser_type
+ - name: order_updated_at_local_datetime
description: >
- The type of browser used by the customer to place the order, which is derived from the user agent.
+ Order last modified timestamp converted to reporting timezone (from order_updated_at UTC).
- - name: order_payment_status
+ - name: order_vendors_csv
description: >
- The financial status of an order, which indicates whether the order has been paid.
+ Comma-separated list of vendors associated with products in the order. Used for multi-vendor order analysis and vendor performance tracking.
- name: primary_order_payment_gateway
description: >
- The technology or service that securely transmitted payment information between the customer, the business, and the payment processor.
+ The technology or service that securely transmitted payment information between the customer, the business, and the payment processor. Special Considerations: For marketplaces (e.g., Amazon), gateway naming and presence may vary from direct-to-consumer platforms.
- - name: order_shipping_country_code
+ - name: sm_channel
description: >
- The two-letter code (ISO 3166-1 format) for the country of the shipping address.
+ Sales channel via hierarchy: (1) exclusion tag 'sm-exclude-order' -> excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -> retail, wholesale tags -> wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.
- - name: order_shipping_country
+ - name: sm_customer_key
description: >
- The country of the shipping address.
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to dim_customers (many:1 - multiple orders per customer). Special Considerations: Some platforms (e.g., TikTok Shop) may provide limited linkage, resulting in NULLs for certain orders.
- - name: order_shipping_city
+ - name: sm_default_channel
description: >
- The city, town, or village of the shipping address.
+ Default channel before overrides, from source name and tags: amazon/tiktok_shop/walmart.com; pos/leap -> retail; wholesale tags -> wholesale; otherwise online_dtc. See sm_channel for final channel.
- - name: order_shipping_zip
+ - name: sm_fbclid
description: >
- The postal code of the shipping address.
+ Facebook Click Identifier (FBCLID) from Meta/Facebook ad campaigns, used to track social media conversions. Present when order originated from Facebook/Instagram ad click-through.
- - name: order_shipping_state
+ - name: sm_gclid
description: >
- The state of the shipping address.
+ Google Click Identifier (GCLID) from Google Ads campaigns, used to track paid search conversions. Present when order originated from Google Ads click-through.
- - name: is_price_tax_inclusive
+ - name: sm_order_key
description: >
- Whether taxes are included in the order subtotal.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Primary key (grain: one row per sm_order_key). Join to dim_order_lines via sm_order_key (1:many), dim_customers via sm_customer_key (many:1).
- - name: sm_default_channel
+ - name: sm_order_landing_page
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags.
+ The URL for the page where the buyer landed when they entered the shop.
- - name: sm_channel
+ - name: sm_order_referrer_domain
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ Domain derived from order_referrer_url.
- - name: sm_sub_channel
+ - name: sm_order_sales_channel
description: >
- The sales sub-channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ Raw sales channel from source system (e.g., 'TikTok Shop', 'Instagram Shop'). Used as input dimension for sm_channel mapping. See sm_channel for final classification.
- - name: sm_utm_source
+ - name: sm_order_type
description: >
- The last touch utm_source value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Skio, Loop, Retextion).
- - name: sm_utm_medium
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: sm_sub_channel
description: >
- The last touch utm_medium value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Sub-channel from source/tags with config overrides (e.g., Facebook & Instagram, Google, Amazon FBA/Fulfilled by Merchant).
- name: sm_utm_campaign
description: >
- The last touch utm_campaign value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Last-click UTM campaign from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- name: sm_utm_content
description: >
- The last touch utm_content value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Last-click UTM content from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: sm_utm_term
+ - name: sm_utm_id
+ description: >
+ SourceMedium-generated unique identifier for UTM parameter combinations on this order. Used to link orders to specific marketing campaigns via UTM tracking.
+
+ - name: sm_utm_medium
+ description: >
+ Last-click UTM medium from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
+
+ - name: sm_utm_source
description: >
- The last touch utm_term value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Last-click UTM source from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- name: sm_utm_source_medium
description: >
- A concatenation of source and medium.
+ Concatenation of source / medium (e.g., 'google / cpc'). Shows '(none) / (none)' when null.
- - name: sm_order_type
+ - name: sm_utm_term
+ description: >
+ Last-click UTM term from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
+
+ - name: source_system
description: >
- The order classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- name: subscription_order_sequence
description: >
- Whether a subscription order is the first subscription order or a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
-```
\ No newline at end of file
+ Subscription lifecycle classification: '1st_sub_order' for initial subscription purchase, 'recurring_sub_order' for renewals, 'one_time_order' for non-subscription orders. Based on subscription order index when available, otherwise inferred from order tags. Use for subscription cohort analysis.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_product_variants.mdx b/data-activation/data-tables/sm_transformed_v2/dim_product_variants.mdx
index 2fc2bb7..4164514 100644
--- a/data-activation/data-tables/sm_transformed_v2/dim_product_variants.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/dim_product_variants.mdx
@@ -1,108 +1,110 @@
---
title: 'dim_product_variants'
-description: ''
+description: 'Product variant dimension for enriching line items with stable keys and attributes.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: dim_product_variants
description: >
- The dim_product_variants table is a dimensional table containing product variant information derived from e-commerce transactions.
+ Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many).
columns:
- - name: smcid
+ - name: inventory_item_id
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ The unique identifier for the inventory item.
- - name: sm_product_variant_key
+ - name: is_product_gift_card
description: >
- The unique product variant key created by SourceMedium that can be used to join product variant dimensions to related tables.
- tests:
- - not_null
- - unique
+ Whether the product is a gift card.
- - name: sm_product_key
+ - name: marketplace_id
description: >
- The unique product key created by SourceMedium that can be used to join product dimensions to related tables.
- tests:
- - not_null
+ Marketplace-specific identifier for the product variant when sold through third-party marketplaces (e.g., Amazon ASIN). NULL for direct-to-consumer sales; used to track marketplace product listings.
- - name: source_system
+ - name: primary_product_image_url
description: >
- The e-commerce source system used to facilitate a customer's order.
+ Primary product image URL (display).
- - name: product_variant_id
+ - name: product_collection_handles_csv
description: >
- A unique identifier for the product variant generated by the source_system.
+ Unique, human-readable strings for the collections a product belongs to automatically generated from their titles.
- - name: product_id
+ - name: product_collection_titles_csv
description: >
- A unique identifier for the product generated by the source_system.
+ The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse.
- - name: sku
+ - name: product_created_at
description: >
- The stock keeping unit (SKU) of the product variant.
+ The date and time when the product was created.
- - name: inventory_item_id
+ - name: product_id
description: >
- The unique identifier for the inventory item.
+ A unique identifier for the product generated by the source_system.
- - name: product_variant_created_at
+ - name: product_tags_csv
description: >
- The date and time when the product variant was created.
+ Tags that the shop owner has attached to the product.
- - name: product_variant_updated_at
+ - name: product_title
description: >
- The date and time when the product variant was last modified.
+ The title of the product.
- - name: product_created_at
+ - name: product_type
description: >
- The date and time when the product was created.
+ A categorization for the product used for filtering and searching for products.
- name: product_updated_at
description: >
The date and time when the product was last modified.
- - name: product_variant_title
+ - name: product_variant_compare_at_price
description: >
- The title of the product variant.
+ The original/compare-at price for this product variant (typically MSRP or pre-sale price). Used to show savings/discounts to customers; NULL if no compare-at price is set.
- - name: product_title
+ - name: product_variant_created_at
description: >
- The title of the product.
+ The date and time when the product variant was created.
- - name: product_type
+ - name: product_variant_id
description: >
- A categorization for the product used for filtering and searching for products.
+ A unique identifier for the product variant generated by the source system.
- - name: primary_product_image
+ - name: product_variant_price
description: >
- A URL used for the primary product image display on the shop.
+ The current retail price for this product variant (per unit). Used for pricing analysis and comparison with order line prices.
- - name: product_collection_titles_csv
+ - name: product_variant_title
description: >
- The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse.
+ The title of the product variant.
- - name: product_collection_handles_csv
+ - name: product_variant_updated_at
description: >
- Unique, human-readable strings for the collections a product belongs to automatically generated from their titles.
+ The date and time when the product variant was last modified.
- - name: product_tags_csv
+ - name: product_vendor
description: >
- Tags that the shop owner has attached to the product.
+ The name of the vendor of the product.
- - name: product_tags_array
+ - name: sku
description: >
- Tags that the shop owner has attached to the product in an array format.
+ The stock keeping unit (SKU) of the product variant.
- - name: product_vendor
+ - name: sm_product_key
description: >
- The name of the vendor of the product.
+ Stable SourceMedium join key for products to related tables.
- - name: is_product_gift_card
+ - name: sm_product_variant_key
description: >
- Whether the product is a gift card.
-```
\ No newline at end of file
+ Stable SourceMedium join key for product variants to related tables.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
+ description: >
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/dim_times.mdx b/data-activation/data-tables/sm_transformed_v2/dim_times.mdx
deleted file mode 100644
index e058bc4..0000000
--- a/data-activation/data-tables/sm_transformed_v2/dim_times.mdx
+++ /dev/null
@@ -1,183 +0,0 @@
----
-title: 'dim_times'
-description: ''
----
-
-```yaml
-version: 2
-
-models:
- - name: dim_times
- description: >
- The dim_times table contains dimensions associated with time.
- columns:
- - name: datetime
- description: >
- The representation of a date and time in the ISO 8601 format.
- tests:
- - not_null
- - unique
- - name: date_day
- description: >
- The representation of a date in YYYY-MM-DD format.
- tests:
- - not_null
- - name: prior_date_day
- description: >
- The representation of a date in YYYY-MM-DD format, one day prior to the date_day.
- tests:
- - not_null
- - name: next_date_day
- description: >
- The representation of a date in YYYY-MM-DD format, one day after the date_day.
- tests:
- - not_null
- - name: prior_year_date_day
- description: >
- The representation of a date in YYYY-MM-DD format, one year prior to the date_day.
- tests:
- - not_null
- - name: prior_year_over_year_date_day
- description: >
- The representation of the date one year prior to the current date in YYYY-MM-DD format, considering the same day and month.
- tests:
- - not_null
- - name: day_of_week
- description: >
- The numerical representation of the day of the week, where Sunday is assigned the value 1 and Saturday is assigned the value 7.
- tests:
- - not_null
- - name: day_of_week_iso
- description: >
- The numerical representation of the day of the week following the ISO 8601 standard, where Monday is assigned the value 1 and Sunday is assigned the value 7.
- tests:
- - not_null
- - name: day_of_week_name
- description: >
- The full name of the day of the week.
- tests:
- - not_null
- - name: day_of_month
- description: >
- The numerical representation of the day of the month.
- tests:
- - not_null
- - name: day_of_year
- description: >
- The numerical representation of the day within a year, ranging from 1 to 365 (or 366 in a leap year).
- tests:
- - not_null
- - name: week_start_date
- description: >
- The representation of the starting date of the week in YYYY-MM-DD format.
- tests:
- - not_null
- - name: week_end_date
- description: >
- The representation of the ending date of the week in YYYY-MM-DD format.
- tests:
- - not_null
- - name: prior_year_week_start_date
- description: >
- The representation of the starting date of the week one year prior to the current week.
- tests:
- - not_null
- - name: prior_year_week_end_date
- description: >
- The representation of the ending date of the week one year prior to the current week.
- tests:
- - not_null
- - name: week_of_year
- description: >
- The numerical representation of the week within a year, ranging from 1 to 52 (or 53 in a leap year).
- tests:
- - not_null
- - name: iso_week_start_date
- description: >
- The representation of the starting date of the week following the ISO 8601 standard in YYYY-MM-DD format.
- tests:
- - not_null
- - name: iso_week_end_date
- description: >
- The representation of the ending date of the week following the ISO 8601 standard in YYYY-MM-DD format.
- tests:
- - not_null
- - name: iso_week_of_year
- description: >
- The numerical representation of the week within a year following the ISO 8601 standard, ranging from 1 to 52 (or 53 in a leap year).
- tests:
- - not_null
- - name: prior_year_iso_week_of_year
- description: >
- The numerical representation of the week within a year following the ISO 8601 standard, ranging from 1 to 52 (or 53 in a leap year), one year prior to the current ISO week.
- tests:
- - not_null
- - name: month_of_year
- description: >
- The numerical representation of the month within a year, ranging from 1 to 12.
- tests:
- - not_null
- - name: month_name
- description: >
- The full name of the month.
- tests:
- - not_null
- - name: month_name_short
- description: >
- The abbreviated name of the month.
- tests:
- - not_null
- - name: month_start_date
- description: >
- The representation of the starting date of the month in YYYY-MM-DD format.
- tests:
- - not_null
- - name: month_end_date
- description: >
- The representation of the ending date of the month in YYYY-MM-DD format.
- tests:
- - not_null
- - name: prior_year_month_start_date
- description: >
- The representation of the starting date of the month one year prior to the current month.
- tests:
- - not_null
- - name: prior_year_month_end_date
- description: >
- The representation of the ending date of the month one year prior to the current month.
- tests:
- - not_null
- - name: quarter_of_year
- description: >
- The numerical representation of the quarter within a year, ranging from 1 to 4.
- tests:
- - not_null
- - name: quarter_start_date
- description: >
- The representation of the starting date of the quarter in YYYY-MM-DD format.
- tests:
- - not_null
- - name: quarter_end_date
- description: >
- The representation of the ending date of the quarter in YYYY-MM-DD format.
- tests:
- - not_null
- - name: year_number
- description: >
- The numerical representation of the year.
- tests:
- - not_null
- - name: year_start_date
- description: >
- The representation of the starting date of the year in YYYY-MM-DD format.
- tests:
- - not_null
- - name: year_end_date
- description: >
- The representation of the ending date of the year in YYYY-MM-DD format.
- tests:
- - not_null
- - name: us_holiday_name
- description: >
- The name of the holiday, if the date is a US holiday.
-```
\ No newline at end of file
diff --git a/data-activation/data-tables/sm_transformed_v2/fct_orders_placed.mdx b/data-activation/data-tables/sm_transformed_v2/fct_orders_placed.mdx
index 808c6eb..ff9477a 100644
--- a/data-activation/data-tables/sm_transformed_v2/fct_orders_placed.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/fct_orders_placed.mdx
@@ -1,88 +1,70 @@
---
title: 'fct_orders_placed'
-description: ''
+description: 'Placed order fact table for order-count analytics and funnel tie-ins.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: fct_orders_placed
description: >
- The fct_orders_placed is a fact table containing information about orders placed by customers.
+ Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1).
columns:
- - name: smcid
+ - name: order_created_at_local_datetime
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ Order created timestamp converted to reporting timezone (from order_created_at UTC).
- - name: sm_order_line_key
+ - name: order_id
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
- tests:
- - not_null
- - unique
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: source_system
+ - name: order_line_gross_sales
description: >
- The e-commerce source system used to facilitate a customer's order.
+ The number of items in an order multiplied by the price of those items.
- - name: sm_order_key
+ - name: order_line_id
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
+ The ID of the order line.
- - name: sm_product_variant_key
+ - name: order_line_price
description: >
- The unique product variant key created by SourceMedium that can be used to join product variant dimensions to related tables.
- tests:
- - not_null
+ The price of the items purchased in an order.
- - name: sm_product_key
+ - name: order_line_quantity
description: >
- The unique product key created by SourceMedium that can be used to join product dimensions to related tables.
- tests:
- - not_null
+ The number of items that were originally purchased in an order.
- - name: order_created_at_local_datetime
+ - name: product_variant_id
description: >
- The autogenerated date and time when the order was created, converted to the reporting timezone configured in SourceMedium.
+ A unique identifier for the product variant generated by the source system.
- name: sm_customer_key
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.
- - name: order_line_id
+ - name: sm_order_key
description: >
- The ID of the order line.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: order_id
+ - name: sm_order_line_key
description: >
- The ID of the order.
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: product_variant_id
+ - name: sm_product_key
description: >
- A unique identifier for the product variant generated by the source_system.
+ Stable SourceMedium join key for products to related tables.
- - name: order_line_quantity
+ - name: sm_product_variant_key
description: >
- The number of items that were originally purchased in an order.
+ Stable SourceMedium join key for product variants to related tables.
- - name: order_line_price
+ - name: sm_store_id
description: >
- The price of the items purchased in an order.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: order_line_gross_sales
+ - name: source_system
description: >
- The number of items in an order multiplied by the price of those items.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- - name: _synced_at
- description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/fct_refunds_processed.mdx b/data-activation/data-tables/sm_transformed_v2/fct_refunds_processed.mdx
index f641aa0..a9e0a60 100644
--- a/data-activation/data-tables/sm_transformed_v2/fct_refunds_processed.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/fct_refunds_processed.mdx
@@ -1,114 +1,90 @@
---
title: 'fct_refunds_processed'
-description: ''
+description: 'Refund transaction fact table for revenue adjustments and return analytics.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: fct_refunds_processed
description: >
- The fct_refunds_processed table is a fact table containing information about processed refunds for a shop.
+ Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1).
columns:
- - name: smcid
+ - name: order_duty_refunds
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ The amount of order duty refunds applied to an order.
- - name: sm_refund_line_key
+ - name: order_id
description: >
- The unique refund line key created by SourceMedium that can be used to join refund line dimensions to related tables.
- tests:
- - not_null
- - unique
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: source_system
+ - name: order_line_id
description: >
- The e-commerce source system used to facilitate a customer's order.
+ The ID of the order line.
- - name: sm_refund_key
+ - name: order_line_refund_quantity
description: >
- The unique refund key created by SourceMedium that can be used to join refund dimensions to related tables.
- tests:
- - not_null
+ The quantity of order lines that were refunded. This value is always negative.
- - name: sm_product_key
+ - name: order_line_refunds
description: >
- The unique product key created by SourceMedium that can be used to join product dimensions to related tables.
- tests:
- - not_null
+ The amount of order line refunds applied to an order.
- - name: sm_product_variant_key
+ - name: order_line_tax_refunds
description: >
- The unique product variant key created by SourceMedium that can be used to join product variant dimensions to related tables.
- tests:
- - not_null
+ The amount of order line tax refunds applied to an order.
- - name: sm_order_line_key
+ - name: refunded_at
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
- tests:
- - not_null
+ The autogenerated date and time when the refund was processed.
- - name: sm_order_key
+ - name: refunded_at_local_datetime
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
+ The autogenerated date and time when the refund was processed, converted to the reporting timezone configured in SourceMedium.
- - name: order_line_id
+ - name: shipping_refunds
description: >
- The ID of the order line.
+ The amount of shipping refunds applied to an order.
- - name: order_id
+ - name: shipping_tax_refunds
description: >
- The ID of the order.
+ The amount of shipping tax refunds applied to an order.
- - name: refunded_at
+ - name: sm_customer_key
description: >
- The autogenerated date and time when the refund was processed.
- tests:
- - not_null
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.
- - name: refunded_at_local_datetime
+ - name: sm_order_key
description: >
- The autogenerated date and time when the refund was processed, converted to the reporting timezone configured in SourceMedium.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: sm_customer_key
+ - name: sm_order_line_key
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: order_line_refund_quantity
+ - name: sm_product_key
description: >
- The quantity of order lines that were refunded. This value is always negative.
+ Stable SourceMedium join key for products to related tables.
- - name: shipping_refunds
+ - name: sm_product_variant_key
description: >
- The amount of shipping refunds applied to an order.
+ Stable SourceMedium join key for product variants to related tables.
- - name: shipping_tax_refunds
+ - name: sm_refund_key
description: >
- The amount of shipping tax refunds applied to an order.
+ The unique refund key created by SourceMedium that can be used to join refund dimensions to related tables.
- - name: order_line_refunds
+ - name: sm_refund_line_key
description: >
- The amount of order line refunds applied to an order.
+ The unique refund line key created by SourceMedium that can be used to join refund line dimensions to related tables.
- - name: order_line_tax_refunds
+ - name: sm_store_id
description: >
- The amount of order line tax refunds applied to an order.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: order_duty_refunds
+ - name: source_system
description: >
- The amount of order duty refunds applied to an order.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- - name: _synced_at
- description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/index.mdx b/data-activation/data-tables/sm_transformed_v2/index.mdx
new file mode 100644
index 0000000..872bb24
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/index.mdx
@@ -0,0 +1,87 @@
+---
+title: "SM Transformed v2 Tables"
+description: "Browse all tables in the sm_transformed_v2 schema, grouped by type."
+icon: "table"
+---
+
+Welcome to the sm_transformed_v2 schema. Use this page to quickly jump to table-level documentation. Tables are grouped by their role in the model for clarity.
+
+### Dimensions
+
+
+ Customer address dimension for enriching customers and orders with normalized geo attributes.
+
+
+ Customer dimension with stable keys and profile attributes for joining and segmentation.
+
+
+ Order discount dimension with discount types, codes, and values.
+
+
+ Order line dimension for product-level attributes at line grain.
+
+
+ Order shipping line dimension for shipping method and cost details at line-level.
+
+
+ Order tax dimension with tax names and amounts for reconciliation and reporting.
+
+
+ Order dimension with stable keys and descriptive attributes for joining and exploration.
+
+
+ Product variant dimension for enriching line items with stable keys and attributes.
+
+
+
+### Facts
+
+
+ Placed order fact table for order-count analytics and funnel tie-ins.
+
+
+ Refund transaction fact table for revenue adjustments and return analytics.
+
+
+
+### OBT (One Big Table)
+
+
+ Customer support ticket analytics for lifecycle, agent performance, and channel analysis.
+
+
+ Customer analytics table for acquisition, subscription status, and cohort analysis.
+
+
+ Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution.
+
+
+ Product-level analytics table for order line revenue, costs, and profitability.
+
+
+ Order analytics table for revenue, profitability, refunds, and channel performance analysis.
+
+
+
+### Reports
+
+
+ Daily advertising performance across platforms for spend, efficiency, and ROAS.
+
+
+ Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters.
+
+
+ Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets).
+
+
+ Hourly funnel event aggregation for near-real-time conversion monitoring.
+
+
+ Daily messaging performance across email/SMS/push for campaigns and flows.
+
+
+
+
+
+Need something else in this index? Ping us and we’ll add it.
diff --git a/data-activation/data-tables/sm_transformed_v2/obt_customer_support_tickets.mdx b/data-activation/data-tables/sm_transformed_v2/obt_customer_support_tickets.mdx
new file mode 100644
index 0000000..679739a
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/obt_customer_support_tickets.mdx
@@ -0,0 +1,174 @@
+---
+title: 'obt_customer_support_tickets'
+description: 'Customer support ticket analytics for lifecycle, agent performance, and channel analysis.'
+icon: "table"
+---
+```yaml
+version: 2
+
+models:
+ - name: obt_customer_support_tickets
+ description: >
+ Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify).
+ columns:
+ - name: customer_id
+ description: >
+ Source of truth customer ID from ecommerce platforms (e.g., Shopify)
+
+ - name: is_ticket_from_agent
+ description: >
+ Indicates whether the ticket was initiated by an agent (true) or customer (false)
+
+ - name: is_ticket_one_touch
+ description: >
+ Flag indicating if the ticket was resolved with a single touch
+
+ - name: is_ticket_spam
+ description: >
+ Whether the ticket is marked as spam
+
+ - name: is_ticket_unread
+ description: >
+ Indicates whether the ticket has unread messages
+
+ - name: sm_channel
+ description: >
+ The sales channel associated with the ticket.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: sm_ticket_key
+ description: >
+ Surrogate key for the ticket
+
+ - name: source_system
+ description: >
+ Source system identifier
+
+ - name: source_system_customer_id
+ description: >
+ Customer identifier from the customer support platform (e.g., Gorgias)
+
+ - name: ticket_assignee_email
+ description: >
+ Full email of the user assigned to the ticket
+
+ - name: ticket_assignee_full_name
+ description: >
+ Full name of the user assigned to the ticket
+
+ - name: ticket_assignee_id
+ description: >
+ Unique identifier for the agent assigned to the ticket. Links to the agent user profile in the customer support platform.
+
+ - name: ticket_assignee_profile_picture_url
+ description: >
+ URL of the assignee's profile picture
+
+ - name: ticket_assignee_team_name
+ description: >
+ Name of the team assigned to the ticket
+
+ - name: ticket_closed_at
+ description: >
+ UTC timestamp when the ticket was closed/resolved. NULL for open tickets; used with ticket_created_at to calculate resolution time.
+
+ - name: ticket_closed_at_local_datetime
+ description: >
+ Ticket closed timestamp in local timezone.
+
+ - name: ticket_communication_channel
+ description: >
+ The specific platform or channel used for ongoing communication with the customer. Represents the "channel" field in Gorgias that indicates where the conversation takes place (instagram-direct-message, email, etc.).
+
+ - name: ticket_created_at
+ description: >
+ Timestamp when the ticket was created (UTC)
+
+ - name: ticket_created_at_local_datetime
+ description: >
+ Timestamp when the ticket was created (local timezone)
+
+ - name: ticket_csat_score
+ description: >
+ The ticket's CSAT score given by the customer
+
+ - name: ticket_custom_field_csv
+ description: >
+ Comma-separated list of custom field ID-value pairs for the ticket
+
+ - name: ticket_customer_email
+ description: >
+ Email address of the customer who created the ticket
+
+ - name: ticket_customer_first_name
+ description: >
+ First name of the customer who created the ticket. Extracted from the customer support platform; may be NULL if not collected.
+
+ - name: ticket_customer_full_name
+ description: >
+ Full name of the customer who created the ticket (concatenation of first and last name). Extracted from the customer support platform; may be NULL if not collected.
+
+ - name: ticket_customer_last_name
+ description: >
+ Last name of the customer who created the ticket. Extracted from the customer support platform; may be NULL if not collected.
+
+ - name: ticket_entry_method
+ description: >
+ The method through which the ticket was initially created in Gorgias. Represents the "via" field in Gorgias that indicates how the first message of the ticket was received or sent from Gorgias (email, helpdesk, api, etc.).
+
+ - name: ticket_excerpt
+ description: >
+ Brief excerpt of the ticket content
+
+ - name: ticket_external_id
+ description: >
+ External system identifier for the ticket
+
+ - name: ticket_id
+ description: >
+ Original ticket identifier from the source system
+
+ - name: ticket_last_message_at
+ description: >
+ UTC timestamp of the last message sent or received in the ticket conversation. Used to track ticket activity and identify stale tickets.
+
+ - name: ticket_last_message_at_local_datetime
+ description: >
+ Timestamp of the last message in the ticket in local timezone.
+
+ - name: ticket_message_count
+ description: >
+ Total number of messages exchanged in the ticket conversation. Includes both customer and agent messages; used for interaction analysis.
+
+ - name: ticket_priority
+ description: >
+ Priority level of the ticket
+
+ - name: ticket_resolution_time_hours
+ description: >
+ Time taken to resolve the ticket in hours. In rare occasions where ticket creation time is after ticket closed time, the resolution time is 0.
+
+ - name: ticket_status
+ description: >
+ Current status of the ticket -- open or closed
+
+ - name: ticket_subject
+ description: >
+ Subject line of the ticket
+
+ - name: ticket_tag_names_csv
+ description: >
+ Comma-separated list of tag names associated with the ticket
+
+ - name: ticket_updated_at
+ description: >
+ UTC timestamp when the ticket was last updated/modified. Tracks any changes to ticket status, assignee, or new messages.
+
+ - name: ticket_updated_at_local_datetime
+ description: >
+ Ticket latest updated timestamp in local timezone.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/obt_customers.mdx b/data-activation/data-tables/sm_transformed_v2/obt_customers.mdx
index d261f97..728889b 100644
--- a/data-activation/data-tables/sm_transformed_v2/obt_customers.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/obt_customers.mdx
@@ -1,137 +1,114 @@
---
title: 'obt_customers'
-description: ''
+description: 'Customer analytics table for acquisition, subscription status, and cohort analysis.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: obt_customers
description: >
- The obt_customers table is SourceMedium's out-of-the-box, "BI-ready" table that contains fully joined customer facts and customer dimensions
- for a shop. This "One Big Table" (OBT) is a denormalized table that is designed to be developer friendly.
+ Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1).
columns:
- - name: smcid
+ - name: customer_address_city
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ City from customer's primary address (free-form). Coverage varies by source_system; Amazon often has NULL/obfuscated data.
- - name: sm_customer_key
+ - name: customer_address_country
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
- - unique
+ Country from customer's primary address (platform-reported names). Coverage varies by source_system; Amazon often has NULL/obfuscated data.
- - name: source_system
+ - name: customer_address_province
description: >
- The e-commerce source system used to facilitate a customer's order.
- tests:
- - not_null
+ The province, state, or district code of the customer's location.
- - name: customer_id
+ - name: customer_address_zip_code
description: >
- The ID of the customer who placed the order.
- tests:
- - not_null
+ The postal code of the customer's location.
- name: customer_created_at
description: >
- The autogenerated date and time when the customer was created.
-
- - name: customer_updated_at
- description: >
- The autogenerated date and time when the customer was last modified.
+ UTC timestamp when the customer was created.
- name: customer_email
description: >
- The customer's email.
+ Customer email address (PII); see customer_email_hashed for privacy‑safe matching.
- name: customer_email_hashed
description: >
- The customer's email hashed.
+ SHA-256 hash of customer email address. Used for privacy-safe customer matching and analytics across systems without exposing PII.
- name: customer_first_name
description: >
- The customer's first name.
+ Customer's first name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.
- - name: customer_last_name
+ - name: customer_id
description: >
- The customer's last name.
+ The ID of the customer who placed the order.
- - name: customer_tags_csv
+ - name: customer_last_name
description: >
- An aggregated list of all tags associated with a customer.
+ Customer's last name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.
- - name: customer_tags_array
+ - name: customer_phone_number
description: >
- An aggregated list of all tags associated with a customer in an array format.
+ Customer's phone number in platform-provided format (varies by source_system). May be NULL if not collected; formatting and country codes not standardized.
- - name: has_customer_consented_to_marketing
+ - name: customer_street_address
description: >
- Whether the customer has consented to receive marketing communications.
+ The customer's street address.
- - name: is_customer_email_verified
+ - name: customer_tags_csv
description: >
- Whether the customer's email has been verified.
+ Comma-separated list of all tags associated with a customer. Use for simple filtering; beware that individual tag values may contain commas.
- - name: _synced_at
+ - name: customer_updated_at
description: >
- The date and time when SourceMedium last successfully synced the row of data.
- tests:
- - not_null
+ UTC timestamp when the customer was last modified.
- - name: first_order_id
+ - name: customer_first_order_id
description: >
The ID of the customer's first order.
- - name: last_order_id
- description: >
- The ID of the customer's last order.
-
- - name: subscription_source_system
+ - name: has_customer_consented_to_marketing
description: >
- The e-commerce source_system used to facilitate a customer's subscription.
+ Whether the customer has consented to receive marketing communications.
- - name: active_subscriptions
+ - name: is_customer_email_verified
description: >
- The number of active subscriptions associated with a customer.
+ Whether the customer's email has been verified.
- - name: subscriber_id
+ - name: customer_last_order_id
description: >
- The ID of the subscriber.
+ The ID of the customer's last order.
- - name: subscriber_status
+ - name: sm_customer_key
description: >
- The status of the subscriber.
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.
- - name: subscriber_created_at
+ - name: sm_store_id
description: >
- The autogenerated date and time when the subscriber was created.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: active_subscription_count
+ - name: source_system
description: >
- The number of active subscriptions associated with a customer.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- - name: customer_street_address
+ - name: subscriber_created_at
description: >
- The customer's street address.
+ The autogenerated date and time when the subscriber was created.
- - name: customer_address_city
+ - name: subscriber_id
description: >
- The city of customer's location.
+ Unique subscription platform identifier when subscription integration configured (e.g., ReCharge, Skio, Loop, Retextion). NULL for non-subscribers; reflects current/most relevant subscription linkage at snapshot time.
- - name: customer_address_country
+ - name: subscriber_status
description: >
- The country of the customer's location.
+ The status of the subscriber.
- - name: customer_address_province
+ - name: subscription_source_system
description: >
- The province, state, or district code of the customer's location.
+ The e-commerce source_system used to facilitate a customer's subscription.
- - name: customer_address_zip_code
- description: >
- The postal code of the customer's location.
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/obt_funnel_event_history.mdx b/data-activation/data-tables/sm_transformed_v2/obt_funnel_event_history.mdx
new file mode 100644
index 0000000..7cf189b
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/obt_funnel_event_history.mdx
@@ -0,0 +1,262 @@
+---
+title: 'obt_funnel_event_history'
+description: 'Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution.'
+icon: "table"
+---
+```yaml
+version: 2
+
+models:
+ - name: obt_funnel_event_history
+ description: >
+ Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id = order_id (many:1) when available.
+ columns:
+ - name: _source_system_relation
+ description: >
+ Internal dbt field identifying which source model this event originated from (e.g., 'int_elevar__funnel_event_history', 'stg_ga4__unified_events'). Used for debugging and understanding data lineage across the union of tracking platforms.
+
+ - name: event_action
+ description: >
+ Event action from analytics platforms (e.g., Google Analytics event action like 'click', 'submit'). Used for understanding specific user interactions within event categories.
+
+ - name: event_category
+ description: >
+ Event category from analytics platforms (e.g., Google Analytics event category). Used for grouping events by type in custom event tracking implementations.
+
+ - name: event_checkout_id
+ description: >
+ Checkout identifier associated with the event when the event occurs during a checkout process. Used to link funnel events to specific checkout sessions for abandoned cart analysis.
+
+ - name: event_checkout_token
+ description: >
+ Unique token for the checkout session associated with the event. Used to track checkout abandonment and recovery flows across multiple events.
+
+ - name: event_currency_code
+ description: >
+ Three-letter ISO 4217 currency code for revenue events (e.g., 'USD', 'EUR', 'GBP'). Used for multi-currency revenue tracking and international market analysis.
+
+ - name: event_customer_id
+ description: >
+ Platform-reported customer identifier associated with the event.
+
+ - name: event_datetime
+ description: >
+ UTC timestamp when the event was synced/ingested into the warehouse. Use event_local_datetime for time-series analysis in the reporting timezone.
+
+ - name: event_experiment_name
+ description: >
+ Name of the A/B test or experiment associated with the event. Used to segment events by experiment variant for testing analysis.
+
+ - name: event_experiment_variant
+ description: >
+ Variant identifier for the A/B test or experiment (e.g., 'control', 'variant_a'). Used to compare funnel performance across experiment variants.
+
+ - name: event_fbclid
+ description: >
+ Facebook Click Identifier (FBCLID) from the event, used for Meta/Facebook ad attribution. Links events to specific Facebook/Instagram ad clicks for conversion tracking.
+
+ - name: event_gclid
+ description: >
+ Google Click Identifier (GCLID) from the event, used for Google Ads attribution. Links events to specific Google Ads clicks for conversion tracking.
+
+ - name: event_id
+ description: >
+ Platform-specific identifier of the event instance.
+
+ - name: event_label
+ description: >
+ Event label from analytics platforms providing additional context about the event. Used for detailed event segmentation and custom tracking analysis.
+
+ - name: event_landing_page_ad_id
+ description: >
+ Facebook/Meta ad ID extracted from the landing page URL parameters (fbadid or ad_id). Used to attribute events to specific Meta advertising campaigns.
+
+ - name: event_local_datetime
+ description: >
+ Event timestamp in the reporting time zone; use for time-series grouping and recency checks.
+
+ - name: event_order_id
+ description: >
+ Associated order ID when the event relates to an order (e.g., purchase).
+
+ - name: event_order_line_subtotal_revenue
+ description: >
+ Line-level subtotal revenue attributed to the event when available.
+
+ - name: event_order_revenue
+ description: >
+ Revenue attributed to the event when applicable (e.g., purchase events).
+
+ - name: event_order_shipping_revenue
+ description: >
+ Shipping revenue attributed to the event when applicable.
+
+ - name: event_order_subtotal_revenue
+ description: >
+ Subtotal revenue (pre-tax, pre-shipping) attributed to the event.
+
+ - name: event_order_taxes
+ description: >
+ Taxes attributed to the event when applicable.
+
+ - name: event_page_path
+ description: >
+ The URL path of the page where the event occurred (e.g., '/products/item-name'). Normalized to remove special characters; use for page grouping in funnel analysis.
+
+ - name: event_page_title
+ description: >
+ The title of the web page where the event occurred (from HTML tag). Used for page-level funnel analysis and identifying specific landing pages.
+
+ - name: event_page_url
+ description: >
+ Page URL with the query parameters removed.
+
+ - name: event_page_url_with_params
+ description: >
+ Page URL with all original query parameters.
+
+ - name: event_referrer
+ description: >
+ The full referrer URL that brought the user to the page where the event occurred. Contains complete referrer information including query parameters.
+
+ - name: event_referrer_domain
+ description: >
+ The domain extracted from the referrer URL that brought the user to the page. Used to identify traffic sources and external sites driving events.
+
+ - name: event_referrer_medium
+ description: >
+ Marketing medium extracted from the referrer URL (e.g., 'organic', 'cpc', 'social'). Used for medium-level attribution when UTM parameters are not available.
+
+ - name: event_referrer_source
+ description: >
+ Marketing source extracted from the referrer URL (e.g., 'google', 'facebook'). Used for source-level attribution when UTM parameters are not available.
+
+ - name: event_referrer_term
+ description: >
+ Search term or keyword extracted from the referrer URL. Used for keyword-level attribution and search query analysis.
+
+ - name: event_referrer_url
+ description: >
+ Full referrer URL including query parameters that brought the user to the page. More detailed than event_referrer; used for complete referrer analysis.
+
+ - name: event_screen_resolution
+ description: >
+ Screen resolution of the device where the event occurred (e.g., '1920x1080'). Used for device-specific funnel optimization and responsive design analysis.
+
+ - name: event_session_id
+ description: >
+ Platform-specific session identifier for the user's browsing session. May differ from event_user_session_id depending on tracking platform; used for session-level analysis.
+
+ - name: event_time
+ description: >
+ Raw event timestamp from the source tracking platform (may be in various formats). Use event_local_datetime for standardized time-series analysis.
+
+ - name: event_user_city
+ description: >
+ City location of the user who triggered the event, derived from IP geolocation or user profile. Used for geographic segmentation and regional funnel analysis.
+
+ - name: event_user_country_code
+ description: >
+ Two-letter ISO country code of the user who triggered the event (e.g., 'US', 'CA', 'GB'). Used for international market segmentation and country-level funnel analysis.
+
+ - name: event_user_email
+ description: >
+ Email address of the user who triggered the event, when available from tracking platform. Used for user identification and linking events to customer records.
+
+ - name: event_user_first_name
+ description: >
+ First name of the user who triggered the event, when available from tracking platform. Used for personalization and user identification.
+
+ - name: event_user_id
+ description: >
+ Platform-reported user identifier (distinct from customer ID) associated with the event.
+
+ - name: event_user_last_name
+ description: >
+ Last name of the user who triggered the event, when available from tracking platform. Used for personalization and user identification.
+
+ - name: event_user_phone
+ description: >
+ Phone number of the user who triggered the event, when available from tracking platform. Format varies by platform; used for user identification in phone-based campaigns.
+
+ - name: event_user_province_code
+ description: >
+ State/province code of the user who triggered the event (e.g., 'CA', 'NY'). Used for regional segmentation and state-level funnel analysis.
+
+ - name: event_user_session_count
+ description: >
+ Session count metric associated with the event/user context when provided by the platform.
+
+ - name: event_user_session_id
+ description: >
+ Session identifier for the user's browsing session when the event occurred. Used to group events into sessions for session-level funnel analysis and pathing.
+
+ - name: event_user_zip_code
+ description: >
+ ZIP/postal code of the user who triggered the event. Used for granular geographic analysis and local market segmentation.
+
+ - name: event_utm_campaign
+ description: >
+ UTM campaign associated with the event (if available).
+
+ - name: event_utm_content
+ description: >
+ UTM content associated with the event (if available).
+
+ - name: event_utm_id
+ description: >
+ UTM ID parameter from the event URL, used for campaign tracking across Google and other platforms. Links events to specific marketing campaign IDs for attribution analysis.
+
+ - name: event_utm_medium
+ description: >
+ UTM medium associated with the event (if available).
+
+ - name: event_utm_source
+ description: >
+ UTM source associated with the event (if available).
+
+ - name: event_utm_term
+ description: >
+ UTM term associated with the event (if available).
+
+ - name: sm_event_key
+ description: >
+ Internal SM event ID that's unique for each row.
+
+ - name: sm_event_name
+ description: >
+ Normalized event name mapped across platforms for consistent funnel analysis.
+
+ - name: sm_funnel_event_rank
+ description: >
+ Sequential rank of the event within the user's funnel journey (1 = first event, 2 = second, etc.). Used for funnel step analysis and understanding user progression through conversion paths.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
+ description: >
+ Tracking platform emitting the event (elevar, blotout, snowplow, snowplow_ga4, heap, ga4).
+
+ - name: source_system_event_local_datetime
+ description: >
+ Original event timestamp from the source tracking platform in its local timezone. May differ from event_local_datetime which uses the reporting timezone; use for debugging timestamp discrepancies.
+
+ - name: source_system_event_name
+ description: >
+ Original event name from the source platform.
+
+ - name: user_ip
+ description: >
+ IP address of the user who triggered the event. Used for geolocation analysis and fraud detection; may be anonymized based on privacy settings.
+
+ - name: user_user_agent
+ description: >
+ Browser user agent string from the event, identifying browser and device type. Used for browser compatibility analysis and device segmentation.
+
+ - name: user_zip
+ description: >
+ ZIP/postal code from user IP geolocation or profile data. Alternative to event_user_zip_code; used for geographic segmentation.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/obt_order_lines.mdx b/data-activation/data-tables/sm_transformed_v2/obt_order_lines.mdx
index 5d57377..2c0b9e0 100644
--- a/data-activation/data-tables/sm_transformed_v2/obt_order_lines.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/obt_order_lines.mdx
@@ -1,390 +1,402 @@
---
title: 'obt_order_lines'
-description: ''
+description: 'Product-level analytics table for order line revenue, costs, and profitability.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: obt_order_lines
description: >
- The obt_order_lines table is SourceMedium's out-of-the-box, "BI-ready" table that contains fully joined order line facts and order line dimensions
- for a shop. This "One Big Table" (obt) is a denormalized table that is designed to be developer friendly.
-
+ Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid = TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1).
columns:
- - name: smcid
+ - name: customer_id
description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
+ The ID of the customer who placed the order.
- - name: sm_order_line_key
+ - name: customer_tags_csv
description: >
- The unique order line key created by SourceMedium that can be used to join order line dimensions to related tables.
- tests:
- - not_null
- - unique
+ Comma-separated customer tags at order time (free-form; convenience string form of array field). Tags may change over time; value reflects state at order processing time.
- - name: sm_order_key
+ - name: earliest_order_refund_date
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
+ The date of the first refund associated with the order line.
- - name: sm_customer_key
+ - name: is_order_line_subscription
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
+ Whether the order line is a susbcription order.
- - name: sm_product_variant_key
+ - name: is_order_only_gift_cards
description: >
- The unique product variant key created by SourceMedium that can be used to join product variant dimensions to related tables.
- tests:
- - not_null
+ Whether the order associated with the line item only contains gift cards.
- - name: order_line_id
+ - name: is_order_sm_valid
description: >
- The ID of the order line.
+ True if order is not voided, cancelled, uncollectible, draft, or refunded. Use WHERE is_order_sm_valid = TRUE to exclude test/invalid orders from revenue.
- - name: order_id
+ - name: is_product_gift_card
description: >
- The ID of the order.
+ Whether the product is a gift card.
- - name: customer_id
+ - name: latest_order_refund_date
description: >
- The ID of the customer.
+ The most recent date a refund was processed for an order.
- - name: order_number
+ - name: order_cart_quantity
description: >
- The order's position in the shop's count of orders.
+ The quantity of items that were originally purchased in an order.
- - name: source_system
+ - name: order_created_at_local_datetime
description: >
- The e-commerce source system used to facilitate a customer's order.
+ Order created timestamp converted to reporting timezone (from order_created_at UTC).
- - name: sm_order_sales_channel
+ - name: order_id
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags.
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: sm_channel
+ - name: order_index
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ An ordered index that can be used to identify the sequential position of an order relative to a customer's order history.
- - name: sm_sub_channel
+ - name: order_line_discount_codes_csv
description: >
- The sales sub-channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ A list of discount codes applied to an order.
- - name: sm_utm_source
+ - name: order_line_discounts
description: >
- The last touch utm_source value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ The amount of discounts applied to an order line.
- - name: sm_utm_medium
+ - name: order_line_duty_refunds
description: >
- The last touch utm_medium value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ The amount of duty refunds applied to an order line.
- - name: sm_utm_source_medium
+ - name: order_line_fulfillment_cost
description: >
- A concatenation of sm_utm_source and sm_utm_medium.
+ The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
- - name: sm_zero_party_attribution_source
+ - name: order_line_gross_duties
description: >
- The attributable source of an order based on order tags associated with a post-purchase survey service provider.
+ The amount the customer paid in duties for an order.
- - name: sm_utm_campaign
+ - name: order_line_gross_profit
description: >
- The last touch utm_campaign value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Net order line revenue and shipping revenue minus order line product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
- - name: is_order_sm_valid
+ - name: order_line_gross_revenue
description: >
- Whether an order is not voided, cancelled, uncollectible, draft, or refunded.
+ The gross revenue for an order line. Gross revenue is calculated by multiplying the price of an order line by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
- - name: valid_order_index
+ - name: order_line_gross_shipping
description: >
- An ordered index that can be used to identify the sequential position of a valid order relative to a customer's valid order history.
+ The amount the customer paid in shipping for an order shipping line. This does not include shipping tax.
- - name: valid_order_index_reversed
+ - name: order_line_gross_shipping_taxes
description: >
- An ordered index in reverse that can be used to identify the sequential position of a valid order relative to a customer's valid order history.
+ The gross shipping tax for an order shipping line.
- - name: sm_order_type
+ - name: order_line_gross_taxes
description: >
- The order classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated.
+ The amount of taxes associated with an order line, after discounts and before returns.
- - name: order_index
+ - name: order_line_id
description: >
- An ordered index that can be used to identify the sequential position of an order relative to a customer's order history.
+ The ID of the order line.
- - name: order_sequence
+ - name: order_line_merchant_processing_fees
description: >
- Whether an order is the acquisition order or a repeat order.
+ The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
- - name: discount_codes_csv
+ - name: order_line_net_duties
description: >
- A list of discount codes applied to an order.
+ The gross order line duties minus order duty refunds.
- - name: subscription_order_sequence
+ - name: order_line_net_quantity
description: >
- Whether a subscription order is the first subscription order or a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
+ The quantity of items that were originally purchased for an order line minus the quantity of items refunded.
- - name: product_id
+ - name: order_line_net_revenue
description: >
- A unique identifier for the product generated by the source system.
+ The gross order line revenue minus order line discounts and refunds.
- - name: product_variant_id
+ - name: order_line_net_revenue_before_refunds
description: >
- A unique identifier for the product variant generated by the source system.
+ The gross order line revenue minus order line discounts.
- - name: is_product_gift_card
+ - name: order_line_net_shipping
description: >
- Whether the product is a gift card.
+ The gross shipping revenue for an order shipping line minus shipping discounts and shipping refunds.
- - name: primary_product_image
+ - name: order_line_net_shipping_taxes
description: >
- A URL used for the primary product image display on the shop.
+ The shipping tax for an order shipping line minus shipping tax refunds.
- - name: product_collection_titles_csv
+ - name: order_line_net_taxes
description: >
- The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse.
+ The gross order line tax minus the order line tax refunds.
- - name: product_collection_handles_csv
+ - name: order_line_product_collection_handles_csv
description: >
Unique, human-readable strings for the collections a product belongs to automatically generated from their titles.
- - name: is_order_only_gift_cards
+ - name: order_line_product_collection_titles_csv
description: >
- Whether the order associated with the line item only contains gift cards.
+ The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse.
- - name: order_processed_at
+ - name: order_line_product_cost
description: >
- The autogenerated date and time when the order was processed.
+ The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify.
- - name: order_created_at_local_datetime
+ - name: order_line_product_gross_profit
description: >
- The autogenerated date and time when the order was created, converted to the reporting timezone configured in SourceMedium.
+ Net order line revenue minus product cost.
- - name: order_processed_at_local_datetime
+ - name: order_line_quantity
description: >
- The autogenerated date and time when the order was processed, converted to the reporting timezone configured in SourceMedium.
+ The quantity of order lines that were originally purchased in an order.
- - name: order_payment_status
+ - name: order_line_refund_quantity
description: >
- The financial status of an order, which indicates whether the order has been paid.
+ The quantity of items purchased for an order line that were refunded.
- - name: order_tags_array
+ - name: order_line_refunds
description: >
- Tags that the shop owner has attached to the order in an array format.
+ The amount of refunds applied to an order line.
- - name: customer_tags_array
+ - name: order_line_return_cost
description: >
- An aggregated list of all tags associated with a customer in an array format.
+ The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
- - name: product_tags_array
+ - name: order_line_shipping_cost
description: >
- Tags that the shop owner has attached to the product in an array format.
+ The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
- - name: order_shipping_country_code
+ - name: order_line_shipping_discounts
description: >
- The two-letter code (ISO 3166-1 format) for the country of the shipping address.
+ The amount of discounts applied to an order shipping line.
- - name: order_shipping_country
+ - name: order_line_shipping_refunds
description: >
- The country of the shipping address.
+ The amount of shipping refunds applied to an order shipping line.
- - name: order_shipping_state
+ - name: order_line_shipping_tax_refunds
description: >
- The state of the shipping address.
+ The amount of shipping tax refunds applied to an order shipping line.
- - name: order_shipping_city
+ - name: order_line_tax_refunds
description: >
- The city, town, or village of the shipping address.
+ The amount of tax refunds applied to an order line.
- - name: order_shipping_zip
+ - name: order_line_total_discounts
description: >
- The postal code of the shipping address.
+ The amount of discounts for an order line.
- - name: product_type
+ - name: order_line_total_refunds
description: >
- A categorization for the product used for filtering and searching for products.
+ The amount of refunds for an order line.
- - name: sku
+ - name: order_line_total_revenue
description: >
- The stock keeping unit (SKU) of the product variant.
+ Total order line revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
- - name: product_title
+ - name: order_line_total_taxes
description: >
- The title of the product.
+ The amount of taxes for an order line minus tax refunds.
- - name: product_variant_title
+ - name: order_line_type
description: >
- The title of the product variant.
+ The order line classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated.
- - name: product_vendor
+ - name: order_number
description: >
- The vendor of the product.
+ The order's position in the shop's count of orders.
- - name: earliest_refund_date
+ - name: order_payment_status
description: >
- The date of the first refund associated with the order line.
+ The financial status of an order, which indicates whether the order has been paid.
- - name: latest_refund_date
+ - name: order_processed_at
description: >
- The most recent date a refund was processed for an order.
+ UTC timestamp from source system when the order was processed.
- - name: order_line_gross_revenue
+ - name: order_processed_at_local_datetime
description: >
- The gross revenue for an order line. Gross revenue is calculated by multiplying the price of an order line by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
+ Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.
- - name: order_line_discounts
+ - name: order_sequence
description: >
- The amount of discounts applied to an order line.
+ Whether an order is the acquisition order or a repeat order.
- - name: order_line_refunds
+ - name: order_shipping_city
description: >
- The amount of refunds applied to an order line.
+ The city, town, or village of the shipping address.
- - name: order_line_net_revenue
+ - name: order_shipping_country
description: >
- The gross order line revenue minus order line discounts and refunds.
+ The country of the shipping address.
- - name: order_line_quantity
+ - name: order_shipping_country_code
description: >
- The quantity of order lines that were originally purchased in an order.
+ The two-letter code (ISO 3166-1 format) for the country of the shipping address.
- - name: order_line_refund_quantity
+ - name: order_shipping_state
description: >
- The quantity of items purchased for an order line that were refunded.
+ The state of the shipping address.
- - name: order_line_net_quantity
+ - name: order_shipping_zip_code
description: >
- The quantity of items that were originally purchased for an order line minus the quantity of items refunded.
+ Postal/ZIP code of the shipping address for the order (country-dependent format; not geo-normalized). Combine with country/state for region-based analysis.
- - name: order_line_gross_taxes
+ - name: order_tags_csv
description: >
- The amount of taxes associated with an order line, after discounts and before returns.
+ Comma-separated order-level tags (free-form strings set by merchant/apps). Prefer array fields for exact matching where available.
- - name: order_line_tax_refunds
+ - name: order_to_refund_days
description: >
- The amount of tax refunds applied to an order line.
+ Days between order processing and first refund (non-negative; NULL when no refund). Calculated from order_processed_at_local_datetime to earliest_order_refund_date.
- - name: order_line_net_taxes
+ - name: order_to_refund_months
description: >
- The gross order line tax minus the order line tax refunds.
+ Months between order processing date and first refund date for the order/line; derived from days using average month length.
- - name: order_line_gross_shipping
+ - name: order_to_refund_weeks
description: >
- The amount the customer paid in shipping for an order shipping line. This does not include shipping tax.
+ Weeks between order processing date and first refund date for the order/line; derived from days and rounded per model logic.
- - name: order_line_shipping_discounts
+ - name: primary_product_image_url
description: >
- The amount of discounts applied to an order shipping line.
+ Primary product image URL (display).
- - name: order_line_shipping_refunds
+ - name: product_id
description: >
- The amount of shipping refunds applied to an order shipping line.
+ A unique identifier for the product generated by the source system. It can be null for Shopify if the order line data did not contain the product_id populated.
- - name: order_line_net_shipping
+ - name: product_tags_csv
description: >
- The gross shipping revenue for an order shipping line minus shipping discounts and shipping refunds.
+ Comma-separated product tags on the line's product (free-form; aggregated from product metadata). Use array for exact match; CSV for quick text filters.
- - name: order_line_gross_shipping_taxes
+ - name: product_title
description: >
- The gross shipping tax for an order shipping line.
+ The title of the product.
- - name: order_line_shipping_tax_refunds
+ - name: product_type
description: >
- The amount of shipping tax refunds applied to an order shipping line.
+ A categorization for the product used for filtering and searching for products.
- - name: order_line_net_shipping_taxes
+ - name: product_variant_compare_at_price
description: >
- The shipping tax for an order shipping line minus shipping tax refunds.
+ The original/compare-at price for the product variant (typically MSRP or pre-sale price). Used to show savings/discounts to customers; may be NULL if no compare-at price set.
- - name: order_line_total_taxes
+ - name: product_variant_id
description: >
- The amount of taxes for an order line minus tax refunds.
+ A unique identifier for the product variant generated by the source system. It can be null for Shopify if the order line data did not contain the product_variant_id populated.
- - name: order_line_total_discounts
+ - name: product_variant_price
description: >
- The amount of discounts for an order line.
+ The price of the product variant at the time of purchase (per unit, before discounts). Use for pricing analysis and discount effectiveness calculations.
- - name: order_line_total_refunds
+ - name: product_variant_title
description: >
- The amount of refunds for an order line.
+ The title of the product variant.
- - name: order_line_net_revenue_before_refunds
+ - name: product_vendor
description: >
- The gross order line revenue minus order line discounts.
+ The vendor of the product.
- - name: order_line_total_revenue
+ - name: sku
description: >
- Total order line revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
+ The stock keeping unit (SKU) of the product variant.
- - name: order_line_gross_duties
+ - name: sm_channel
description: >
- The amount the customer paid in duties for an order.
+ Sales channel via hierarchy: (1) exclusion tag 'sm-exclude-order' -> excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -> retail, wholesale tags -> wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.
- - name: order_line_duty_refunds
+ - name: sm_customer_key
description: >
- The amount of duty refunds applied to an order line.
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_customers (many:1 - multiple order lines per customer).
- - name: order_line_net_duties
+ - name: sm_order_key
description: >
- The gross order line duties minus order duty refunds.
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_orders (many:1 - multiple order lines per order).
- - name: shipping_cost
+ - name: sm_order_line_key
description: >
- The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+ Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.
- - name: cost_of_returns
+ - name: sm_order_sales_channel
description: >
- The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+ The sales channel associated with an order, which is derived from the order source name and order tags.
- - name: fulfillment_cost
+ - name: sm_order_type
description: >
- The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
+ Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Stay.ai).
- - name: merchant_processing_fees
+ - name: sm_product_variant_key
description: >
- The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
+ Stable SourceMedium join key for product variants to related tables.
- - name: source_system_configured_product_cost
+ - name: sm_store_id
description: >
- The landed cost of an order line as defined by the costs configured in source system multiplied by the quantity purchased.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: user_configured_product_cost
+ - name: sm_sub_channel
description: >
- The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet multiplied by the quantity purchased.
+ The sales sub-channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
- - name: product_cost
+ - name: sm_utm_campaign
description: >
- The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify.
+ Last-click UTM campaign from the attribution source hierarchy (Shopify visits/landing/notes -> website events -> GA/GA4 -> referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata.
- - name: order_cart_quantity
+ - name: sm_utm_id
description: >
- The quantity of items that were originally purchased in an order.
+ SourceMedium-generated unique identifier for UTM parameter combinations on this order line. Enables join to UTM attribution data for marketing campaign analysis.
- - name: product_gross_profit
+ - name: sm_utm_medium
description: >
- Net order line revenue minus product cost.
+ Last-click UTM medium from the attribution source hierarchy (Shopify visits/landing/notes -> website events -> GA/GA4 -> referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata.
- - name: gross_profit
+ - name: sm_utm_source
description: >
- Net order line revenue and shipping revenue minus order line product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
+ Last-click UTM source from the attribution source hierarchy (Shopify visits/landing/notes -> website events -> GA/GA4 -> referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata.
- - name: line_type
+ - name: sm_utm_source_medium
description: >
- The order line classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated.
+ A concatenation of sm_utm_source and sm_utm_medium.
- - name: is_order_line_subscription
+ - name: sm_valid_order_index
description: >
- Whether the order line is a susbcription order.
+ Ordered index identifying the sequential position of a valid order in a customer's valid order history. Only counts orders where is_order_sm_valid = TRUE. See order_sequence for all orders.
- - name: subscription_order_index
+ - name: sm_valid_order_index_reversed
+ description: >
+ An ordered index in reverse that can be used to identify the sequential position of a valid order relative to a customer's valid order history.
+
+ - name: sm_zero_party_attribution_source
+ description: >
+ Attributable source from post‑purchase survey tags (e.g., Fairing/Enquire).
+
+ - name: source_system
+ description: >
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
+
+ - name: source_system_configured_product_cost
description: >
- An ordered index that can be used to identify the sequential position of a subscription order relative to a customer's subscription order history.
+ Landed cost from platform-configured product costs (not SourceMedium configuration sheet). For config-sheet costs, see user_configured_product_cost.
- name: subscription_id
description: >
The ID of the subscription.
-```
\ No newline at end of file
+
+ - name: subscription_order_index
+ description: >
+ Ordered index identifying the sequential position of a subscription order in a customer's subscription order history.
+
+ - name: subscription_order_sequence
+ description: >
+ Whether a subscription order is the first subscription order or a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
+
+ - name: user_configured_product_cost
+ description: >
+ The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet multiplied by the quantity purchased.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/obt_orders.mdx b/data-activation/data-tables/sm_transformed_v2/obt_orders.mdx
index 5698650..a976889 100644
--- a/data-activation/data-tables/sm_transformed_v2/obt_orders.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/obt_orders.mdx
@@ -1,281 +1,267 @@
---
title: 'obt_orders'
-description: ''
+description: 'Order analytics table for revenue, profitability, refunds, and channel performance analysis.'
+icon: "table"
---
-
-
```yaml
version: 2
models:
- name: obt_orders
description: >
- The obt_orders table is SourceMedium's out-of-the-box, "BI-ready" table that contains fully joined order facts and order dimensions
- for a shop. This "One Big Table" (OBT) is a denormalized table that is designed to be developer friendly.
-
+ Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid = TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1).
columns:
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: sm_order_key
+ - name: customer_device_type
description: >
- The unique order key created by SourceMedium that can be used to join order dimensions to related tables.
- tests:
- - not_null
- - unique
+ Device type derived from user agent (e.g., mobile, desktop, tablet). Coverage depends on website tracking; limited for marketplaces.
- - name: sm_customer_key
+ - name: customer_email_hashed
description: >
- The unique customer key created by SourceMedium that can be used to join customer dimensions to related tables.
- tests:
- - not_null
+ A hashed version of the customer's email address.
- - name: source_system
+ - name: customer_id
description: >
- The e-commerce source system used to facilitate a customer's order.
+ The ID of the customer who placed the order.
- - name: order_id
+ - name: customer_tags_csv
description: >
- The ID of the order.
+ Comma-separated customer tags at time of order. Beware that individual tag values may contain commas.
- - name: customer_id
+ - name: earliest_order_refund_date
description: >
- The ID of the customer.
+ The earliest date when a refund was processed for an order.
- - name: order_name
+ - name: gross_profit
description: >
- A separate unique identifier for the order generated by the source system.
+ Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
- - name: order_number
+ - name: is_first_subscription_order
description: >
- The order's position in the shop's count of orders.
+ Whether a subscription order is the first subscription order based on the subscription order index or order tag indicators when an index is not available.
- - name: order_checkout_id
+ - name: is_latest_order
description: >
- The ID of the checkout that the order is associated with.
+ Whether an order has an order_index_reversed that equals 1.
- - name: order_currency
+ - name: is_recurring_subscription_order
description: >
- The three-letter code (ISO 4217 format) for the currency used for the tender transaction.
+ Whether a subscription order is a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
- - name: order_created_at
+ - name: is_order_sm_valid
description: >
- The autogenerated date and time when the order was created.
+ True if order is not voided, cancelled, uncollectible, draft, or refunded. Use WHERE is_order_sm_valid = TRUE to exclude test/invalid orders from revenue.
- - name: order_created_at_local_datetime
+ - name: is_price_tax_inclusive
description: >
- The autogenerated date and time when the order was created, converted to the reporting timezone configured in SourceMedium.
+ Whether taxes are included in the order subtotal.
- - name: order_updated_at
+ - name: is_subscription_order
description: >
- The autogenerated date and time when the order was last updated.
+ Whether the order is a subscription order.
- - name: order_updated_at_local_datetime
+ - name: latest_order_refund_date
description: >
- The autogenerated date and time when the order was last updated, converted to the reporting timezone configured in SourceMedium.
-
- - name: order_processed_at
- description: >
- The autogenerated date and time when the order was processed.
+ The most recent date when a refund was processed for an order.
- - name: order_processed_at_local_datetime
+ - name: order_cancellation_reason
description: >
- The autogenerated date and time when the order was processed, converted to the reporting timezone configured in SourceMedium.
+ The customer's reason for the order's cancellation.
- name: order_cancelled_at
description: >
- The autogenerated date and time when the order was cancelled.
+ UTC timestamp when the order was cancelled. Null if order has not been cancelled.
- name: order_cancelled_at_local_datetime
description: >
- The autogenerated date and time when the order was cancelled, converted to the reporting timezone configured in SourceMedium.
+ Order cancelled timestamp converted to reporting timezone (from order_cancelled_at UTC). Null if order has not been cancelled.
- - name: order_cancellation_reason
+ - name: order_cart_net_quantity
description: >
- The customer's reason for the order's cancellation.
+ The quantity of items that were originally purchased in an order minus the quantity of items refunded.
- - name: sm_order_sales_channel
+ - name: order_cart_quantity
description: >
- The name of the sales channel used to place an order, which is derived from the order source name, payment gateway name, and order tags.
+ The quantity of items that were originally purchased in an order.
- - name: order_source_name
+ - name: order_checkout_id
description: >
- Where the order originated as reported by the source system.
+ The ID of the checkout that the order is associated with.
- - name: order_referring_site
+ - name: order_created_at
description: >
- The URL of the site that referred the customer to the shop.
+ UTC timestamp when the order was created.
- - name: sm_order_referrer_source
+ - name: order_created_at_local_datetime
description: >
- A cleaned version of the website where the customer clicked a link to the shop.
+ Order created timestamp converted to reporting timezone (from order_created_at UTC).
- - name: sm_order_landing_page
+ - name: order_currency_code
description: >
- The URL for the page where the buyer landed when they entered the shop.
+ Three-letter ISO 4217 currency code used to price and settle the order (e.g., USD, CAD, EUR). Multi-currency brands should normalize for FX when comparing revenue across currencies.
- - name: sm_order_referrer_domain
+ - name: order_customer_street_address
description: >
- The domain of the website where the customer clicked a link to the shop.
+ Customer's billing street address associated with the order. May differ from shipping address; use for billing analysis and fraud detection.
- - name: order_index
+ - name: order_discount_codes_csv
description: >
- An ordered index that can be used to identify the sequential position of an order relative to a customer's order history.
+ A list of discount codes applied to an order.
- - name: order_index_reversed
+ - name: order_discounts
description: >
- An ordered index that can be used to identify the sequential position of an order relative to a customer's order history, in reverse order.
+ The total amount of discounts applied to an order.
- - name: order_tags_csv
+ - name: order_duty_refunds
description: >
- A list of tags that the shop owner has attached to the order.
+ The amount of duty refunds applied to an order.
- - name: order_tags_array
+ - name: order_fulfillment_cost
description: >
- A list of tags that the shop owner has attached to the order in an array format.
+ The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
- - name: order_sequence
+ - name: order_gross_duties
description: >
- Whether an order is the first order or a repeat order.
+ The amount the customer paid in duties for an order.
- - name: order_session_user_agent
+ - name: order_gross_revenue
description: >
- The user agent of the device used by the customer to place the order.
+ The gross revenue for an order, based on an order's lines. Gross revenue is calculated by multiplying the price of an order's lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
- - name: customer_device_type
+ - name: order_gross_shipping
description: >
- The type of device used by the customer to place the order, which is derived from the user agent.
+ The amount the customer paid in shipping for an order. This does not include shipping tax.
- - name: order_session_browser_type
+ - name: order_gross_shipping_taxes
description: >
- The type of browser used by the customer to place the order, which is derived from the user agent.
+ The amount of taxes associated with shipping, after discounts and before returns.
- - name: order_payment_status
+ - name: order_gross_taxes
description: >
- The financial status of an order, which indicates whether the order has been paid.
+ The amount of taxes associated with an order's lines, after discounts and before returns. This does not include shipping taxes.
- - name: primary_order_payment_gateway
+ - name: order_id
description: >
- The technology or service that securely transmitted payment information between the customer, the business, and the payment processor.
+ Platform order identifier. Not globally unique across stores; pair with `sm_store_id` and `source_system` when needed for scoping.
- - name: order_shipping_country_code
+ - name: order_index
description: >
- The two-letter code (ISO 3166-1 format) for the country of the shipping address.
+ Ordered index identifying the sequential position of an order in a customer's order history.
- - name: order_shipping_country
+ - name: order_index_reversed
description: >
- The country of the shipping address.
+ Ordered index identifying the sequential position of an order in a customer's order history, in reverse order.
- - name: order_shipping_city
+ - name: order_latency_days
description: >
- The city, town, or village of the shipping address.
+ The number of days between the order_created_at and the order_processed_at for an order.
- - name: order_shipping_zip
+ - name: order_merchant_processing_fees
description: >
- The postal code of the shipping address.
+ The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
- - name: order_shipping_state
+ - name: order_name
description: >
- The state of the shipping address.
+ Platform-rendered name (human‑readable or platform‑specific). Not a stable join key.
- - name: is_price_tax_inclusive
+ - name: order_net_duties
description: >
- Whether taxes are included in the order subtotal.
+ The gross order duties minus duty refunds.
- - name: sm_default_channel
+ - name: order_net_revenue
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags.
+ The gross order revenue minus order discounts and refunds.
- - name: sm_channel
+ - name: order_net_revenue_before_refunds
description: >
- The sales channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ The gross order revenue minus order discounts.
- - name: sm_sub_channel
+ - name: order_net_shipping
description: >
- The sales sub-channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
+ The gross shipping revenue for an order minus shipping discounts and shipping refunds.
- - name: sm_utm_source
+ - name: order_net_shipping_taxes
+ description: >
+ The order shipping tax minus shipping tax refunds.
+
+ - name: order_net_taxes
description: >
- The last touch utm_source value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ The order tax minus order tax refunds. This does not include shipping taxes.
- - name: sm_utm_medium
+ - name: order_number
description: >
- The last touch utm_medium value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Shop-scoped sequence number assigned by the platform. Not globally unique; pair with `sm_store_id` for scoping.
- - name: sm_utm_campaign
+ - name: order_payment_status
description: >
- The last touch utm_campaign value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Financial status of the order (e.g., paid, partially_paid, partially_refunded, authorized, pending, refunded, voided, draft). Platform‑defined.
- - name: sm_utm_content
+ - name: order_processed_at
description: >
- The last touch utm_content value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ UTC timestamp when the order was processed.
- - name: sm_utm_term
+ - name: order_processed_at_local_datetime
description: >
- The last touch utm_term value associated with an order, which is derived from Shopify notes data, Shopify customer visits data, and GA or GA4 events.
+ Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.
- - name: sm_utm_source_medium
+ - name: order_processing_method
description: >
- A concatenation of source and medium.
+ Method used to process the order (e.g., 'manual', 'direct', 'offsite'). Platform-defined strings; some methods may only appear for specific integrations.
- - name: sm_order_type
+ - name: order_product_tags_csv
description: >
- The order classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated.
+ Comma-separated list of product tags from items in the order (free-form, merchant-defined). Tags can be inconsistent across platforms; prefer normalized dimensional attributes when available.
- - name: subscription_order_sequence
+ - name: order_product_titles_csv
description: >
- Whether a subscription order is the first subscription order or a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
+ A list of product titles included in an order.
- - name: customer_email_hashed
+ - name: order_product_variant_titles_csv
description: >
- A hashed version of the customer's email address.
+ A list of product variant titles included in an order.
- - name: gross_order_revenue
+ - name: order_referrer_url
description: >
- The gross revenue for an order, based on an order's lines. Gross revenue is calculated by multiplying the price of an order's lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
+ The URL of the site that referred the customer to the shop.
- - name: order_discounts
+ - name: order_refund_quantity
description: >
- The total amount of discounts applied to an order.
+ The quantity of order lines originally purchased in an order that were refunded.
- name: order_refunds
description: >
The total amount of refunds applied to an order.
- - name: order_net_revenue
+ - name: order_return_cost
description: >
- The gross order revenue minus order discounts and refunds.
+ The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
- - name: order_quantity
+ - name: order_sequence
description: >
- The quantity of order lines that were originally purchased in an order.
+ Customer lifecycle classification: '1st_order' for new customers, 'repeat_order' for returning customers. Includes all orders (valid + invalid). Use for cohort analysis and retention reporting. See sm_valid_order_index for valid-only ordering.
- - name: order_refund_quantity
+ - name: order_session_browser_type
description: >
- The quantity of order lines originally purchased in an order that were refunded.
+ Browser type derived from user agent (e.g., chrome, safari, firefox). Coverage depends on website tracking; limited for marketplaces.
- - name: order_net_quantity
+ - name: order_session_user_agent
description: >
- The quantity of items that were originally purchased in an order minus the quantity of items refunded.
+ Raw user agent string. Used to derive customer_device_type and order_session_browser_type.
- - name: gross_order_taxes
+ - name: order_shipping_city
description: >
- The amount of taxes associated with an order's lines, after discounts and before returns. This does not include shipping taxes.
+ The city, town, or village of the shipping address.
- - name: order_tax_refunds
+ - name: order_shipping_cost
description: >
- The amount of tax refunds applied to an order. This does not include shipping tax refunds.
+ The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
- - name: order_net_taxes
+ - name: order_shipping_country
description: >
- The order tax minus order tax refunds. This does not include shipping taxes.
+ The country of the shipping address.
- - name: gross_order_shipping
+ - name: order_shipping_country_code
description: >
- The amount the customer paid in shipping for an order. This does not include shipping tax.
+ The two-letter code (ISO 3166-1 format) for the country of the shipping address.
- name: order_shipping_discounts
description: >
@@ -285,227 +271,204 @@ models:
description: >
The amount of shipping refunds applied to an order.
- - name: order_net_shipping
- description: >
- The gross shipping revenue for an order minus shipping discounts and shipping refunds.
-
- - name: gross_order_shipping_taxes
+ - name: order_shipping_state
description: >
- The amount of taxes associated with shipping, after discounts and before returns.
+ Province/state of the shipping address; format varies by country and platform.
- name: order_shipping_tax_refunds
description: >
The amount of shipping tax refunds applied to an order.
- - name: order_net_shipping_taxes
+ - name: order_shipping_zip_code
description: >
- The order shipping tax minus shipping tax refunds.
+ Postal/ZIP code from the shipping address (alphanumeric, varies by country). Use with country and state to avoid ambiguity; not geo-normalized.
- - name: order_total_taxes
+ - name: order_skus_csv
description: >
- The amount of order and shipping taxes minus order and shipping tax refunds.
+ A list of SKUs included in an order.
- - name: order_total_discounts
+ - name: source_system_sales_channel
description: >
- The amount of order and shipping discounts for an order.
+ Original source reported by the platform (e.g., Shopify sales channel/app name).
- - name: order_total_refunds
+ - name: order_tags_csv
description: >
- The amount of order and shipping refunds.
+ Comma-separated list of tags that the shop owner has attached to the order. Use for simple filtering; beware that individual tag values may contain commas.
- - name: order_net_revenue_before_refunds
+ - name: order_tax_refunds
description: >
- The gross order revenue minus order discounts.
+ The amount of tax refunds applied to an order. This does not include shipping tax refunds.
- - name: order_total_revenue
+ - name: order_to_refund_days_earliest
description: >
- Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
+ The number of days between the process date and the first refund date for an order.
- - name: gross_order_duties
+ - name: order_to_refund_days_latest
description: >
- The amount the customer paid in duties for an order.
+ The number of days between the process date and the most recent refund date for an order.
- - name: order_duty_refunds
+ - name: order_to_refund_months_earliest
description: >
- The amount of duty refunds applied to an order.
+ The number of months between the process date and the first refund date for an order.
- - name: order_net_duties
+ - name: order_to_refund_months_latest
description: >
- The gross order duties minus duty refunds.
+ The number of months between the process date and the most recent refund date for an order.
- - name: shipping_cost
+ - name: order_to_refund_weeks_earliest
description: >
- The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+ The number of weeks between the process date and the first refund date for an order.
- - name: cost_of_returns
+ - name: order_to_refund_weeks_latest
description: >
- The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+ The number of weeks between the process date and the most recent refund date for an order.
- - name: fulfillment_cost
+ - name: order_total_discounts
description: >
- The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
+ The amount of order and shipping discounts for an order.
- - name: merchant_processing_fees
+ - name: order_total_refunds
description: >
- The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
+ The amount of order and shipping refunds.
- - name: sm_zero_party_attribution_source
+ - name: order_total_revenue
description: >
- The attributable source of an order based on order tags associated with a post-purchase survey service provider.
+ Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
- - name: discount_codes_csv
+ - name: order_total_taxes
description: >
- A list of discount codes applied to an order.
+ The amount of order and shipping taxes minus order and shipping tax refunds.
- - name: is_order_sm_valid
+ - name: order_updated_at
description: >
- Whether an order is not voided, cancelled, uncollectible, draft, or refunded.
+ UTC timestamp from source system when the order was last updated.
- - name: valid_order_index
+ - name: order_updated_at_local_datetime
description: >
- An ordered index that can be used to identify the sequential position of a valid order relative to a customer's valid order history.
+ Order last updated timestamp converted to reporting timezone (from order_updated_at UTC).
- - name: valid_order_index_reversed
+ - name: order_vendors_csv
description: >
- An ordered index that can be used to identify the sequential position of a valid order relative to a customer's valid order history, in reverse order.
+ Comma-separated list of product vendors in the order, aggregated from line items. Vendor names may vary by platform; use for vendor mix analysis at order level.
- - name: product_cost
+ - name: primary_order_payment_gateway
description: >
- The landed cost of an order as defined by the SourceMedium financial cost configuration sheet (or by costs input directly into Shopify) multiplied by the quantity purchased.
+ The technology or service that securely transmitted payment information between the customer, the business, and the payment processor.
- - name: gross_profit
+ - name: product_cost
description: >
- Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
+ The landed cost of an order as defined by the SourceMedium financial cost configuration sheet (or by costs input directly into Shopify) multiplied by the quantity purchased.
- name: product_gross_profit
description: >
Net order revenue minus product cost.
- - name: subscription_order_index
- description: >
- An ordered index that can be used to identify the sequential position of a subscription order relative to a customer's subscription order history.
-
- - name: earliest_refund_date
- description: >
- The date of the first refund associated with an order.
-
- - name: latest_refund_date
- description: >
- The earliest date when a refund was processed for an order.
-
- - name: skus_csv
- description: >
- A list of SKUs included in an order.
-
- - name: product_titles_csv
+ - name: sm_channel
description: >
- A list of product titles included in an order.
+ Sales channel via hierarchy: (1) exclusion tag 'sm-exclude-order' -> excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -> retail, wholesale tags -> wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.
- - name: product_variant_titles_csv
+ - name: sm_customer_key
description: >
- A list of product variant titles included in an order.
+ Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_customers (many:1 - multiple orders per customer).
- - name: order_cart_quantity
+ - name: sm_default_channel
description: >
- The quantity of items that were originally purchased in an order.
+ Default channel before overrides, from source name and tags: amazon/tiktok_shop/walmart.com; pos/leap -> retail; wholesale tags -> wholesale; otherwise online_dtc. See sm_channel for final channel.
- - name: sm_utm_source_grouped
+ - name: sm_fbclid
description: >
- The last touch order source mapped to a cleaned version of the source platform (e.g. Meta, TikTok, Klaviyo).
+ Facebook Click Identifier (FBCLID) from Meta/Facebook ad campaigns, used to track social media conversions. Present when order originated from Facebook/Instagram ad click-through.
- - name: sm_zero_party_attribution_source_grouped
+ - name: sm_gclid
description: >
- The last touch order source based on zero party attribution mapped a cleaned version of the source platform (e.g., Meta, TikTok, Klaviyo).
+ Google Click Identifier (GCLID) from Google Ads campaigns, used to track paid search conversions. Present when order originated from Google Ads click-through.
- - name: sm_utm_medium_grouped
+ - name: sm_order_key
description: >
- The last touch order medium mapped to a cleaned version of the medium platform (e.g., Social, Email, Search).
+ Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Primary key (grain: one row per sm_order_key). Join to obt_order_lines via sm_order_key (1:many), obt_customers via sm_customer_key (many:1), dim_orders via sm_order_key (1:1).
- - name: sm_zero_party_attribution_medium_grouped
+ - name: sm_order_landing_page
description: >
- The last touch order medium based on zero party attribution mapped to a cleaned version of the medium platform (e.g., Social, Email, Search).
+ The URL for the page where the buyer landed when they entered the shop.
- - name: subscription_order_gross_revenue
+ - name: sm_order_referrer_domain
description: >
- The gross revenue for a subscription order, based on an order's lines. Gross revenue is calculated by multiplying the price of an order's lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
+ Domain derived from order_referrer_url.
- - name: sub_order_net_revenue
+ - name: sm_order_sales_channel
description: >
- The gross order revenue minus discounts and refunds for subscription orders.
+ Raw sales channel from source system (e.g., 'TikTok Shop', 'Instagram Shop'). Used as input dimension for sm_channel mapping. See sm_channel for final classification.
- - name: earliest_subscription_order_net_revenue
+ - name: sm_order_type
description: >
- The gross order revenue minus discounts and refunds for the first subscription order.
+ Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Skio, Loop, Retextion).
- - name: recurring_sub_order_net_revenue
+ - name: sm_store_id
description: >
- The gross order revenue minus discounts and refunds for recurring subscription orders.
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- - name: is_subscription_order
+ - name: sm_sub_channel
description: >
- Whether the order is a subscription order.
+ Sub-channel from source/tags with config overrides (e.g., Facebook & Instagram, Google, Amazon FBA/Fulfilled by Merchant).
- - name: is_first_sub_order
+ - name: sm_utm_campaign
description: >
- Whether a subscription order is the first subscription order based on the subscription order index or order tag indicators when an index is not available.
+ Last-click UTM campaign from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: is_order_recurring_subscription
+ - name: sm_utm_content
description: >
- Whether a subscription order is a repeat subscription order based on the subscription order index or order tag indicators when an index is not available.
+ Last-click UTM content from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: is_latest_order
+ - name: sm_utm_id
description: >
- Whether an order has an order_index_reversed that equals 1.
+ SourceMedium-generated unique identifier for UTM parameter combinations on this order. Used to link orders to specific marketing campaigns via UTM tracking.
- - name: earliest_refund_date
+ - name: sm_utm_medium
description: >
- The earliest date when a refund was processed for an order.
+ Last-click UTM medium from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: latest_refund_date
+ - name: sm_utm_source
description: >
- The most recent date when a refund was processed for an order.
+ Last-click UTM source from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: order_to_refund_days_earliest
+ - name: sm_utm_source_medium
description: >
- The number of days between the process date and the first refund date for an order.
+ Concatenation of source / medium (e.g., 'google / cpc'). Shows '(none) / (none)' when null.
- - name: order_to_refund_days_latest
+ - name: sm_utm_term
description: >
- The number of days between the process date and the most recent refund date for an order.
+ Last-click UTM term from attribution source hierarchy (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.
- - name: order_to_refund_weeks_earliest
+ - name: sm_valid_order_index
description: >
- The number of weeks between the process date and the first refund date for an order.
+ Ordered index identifying the sequential position of a valid order in a customer's valid order history. Only counts orders where is_order_sm_valid = TRUE. See order_sequence for all orders.
- - name: order_to_refund_weeks_latest
+ - name: sm_valid_order_index_reversed
description: >
- The number of weeks between the process date and the most recent refund date for an order.
+ An ordered index that can be used to identify the sequential position of a valid order relative to a customer's valid order history, in reverse order.
- - name: order_to_refund_months_earliest
+ - name: sm_valid_order_latency_days
description: >
- The number of months between the process date and the first refund date for an order.
+ The number of days between the process date of a valid order and the process date of the most recent preceding valid order for a customer.
- - name: order_to_refund_months_latest
+ - name: sm_valid_order_sequence
description: >
- The number of months between the process date and the most recent refund date for an order.
+ Whether a valid order is the first valid order or a repeat valid order.
- - name: order_latency_days
+ - name: sm_zero_party_attribution_source
description: >
- The number of days between the order_created_at and the order_processed_at for an order.
+ Attributable source from post‑purchase survey tags (e.g., Fairing/Enquire).
- - name: order_latency_days_by_type
+ - name: source_system
description: >
- The number of days between the order_created_at and the order_processed_at for an order, grouped by order type.
+ Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.
- - name: valid_order_latency_days
+ - name: subscription_order_index
description: >
- The number of days between the process date of a valid order and the process date of the most recent preceding valid order for a customer.
+ Ordered index identifying the sequential position of a subscription order in a customer's subscription order history.
- - name: valid_order_latency_days_by_type
+ - name: subscription_order_sequence
description: >
- The number of days between the process date of a valid order and the process date of the most recent preceding valid order of the same type for a customer.
+ Subscription lifecycle classification: 'First Subscription Order' for initial subscription purchase, 'Repeat Subscription Order' for renewals. Based on subscription order index when available, otherwise inferred from order tags. Use for subscription cohort analysis.
- - name: valid_order_sequence
- description: >
- Whether a valid order is the first valid order or a repeat valid order.
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily.mdx b/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily.mdx
index 9b9a318..4ad0ef0 100644
--- a/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily.mdx
@@ -1,66 +1,27 @@
---
title: 'rpt_ad_performance_daily'
-description: ''
+description: 'Daily advertising performance across platforms for spend, efficiency, and ROAS.'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: rpt_ad_performance_daily
description: >
- The rpt_marketing_performance_daily table is a report table containing daily advertising performance data. This includes data from all
- advertising platforms integrated with SourceMedium, and provides daily aggregated metrics such as spend, clicks, impressions, conversions, and
- revenue at creative and date-level granularity. This report (RPT) table is optimized for building dashboards.
-
+ Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (sm_store_id, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel).
columns:
- - name: sm_master_account_id
- description: >
- The unique identifier for the master account that is associated with the SourceMedium smcid.
-
- - name: store_name
- description: >
- The name of the store that is associated with the SourceMedium smcid.
-
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: source_system
+ - name: sm_store_id
description: >
- The advertising source system used to deliver the ad.
- tests:
- - not_null
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
- name: ad_account_id
description: >
The unique identifier for the ad account that is associated with the ad.
-
+
- name: ad_account_name
description: >
The name of the ad account that is associated with the ad.
-
- - name: ad_spend
- description: >
- The amount of money spent on the ad.
-
- - name: ad_clicks
- description: >
- The number of times the ad was clicked.
-
- - name: ad_impressions
- description: >
- The number of times the ad was shown.
-
- - name: ad_platform_reported_conversions
- description: >
- The number of conversions attributable to the ad, as reported by the advertising platform.
-
- - name: ad_platform_reported_revenue
- description: >
- The amount of revenue attributable to the ad, as reported by the advertising platform.
- name: ad_campaign_id
description: >
@@ -70,102 +31,140 @@ models:
description: >
The name of the campaign that is associated with the ad.
- - name: ad_name
+ - name: ad_campaign_tactic
description: >
- The name of the ad.
+ The tactic of the campaign derived from campaign naming conventions. Possible values are "Prospecting", "Retargeting", and "Brand". Default is "Prospecting".
- name: ad_campaign_type
description: >
The type of campaign that is associated with the ad, such as reach, discovery, search, display, or video (this campaign type will vary by advertising platform).
-
- - name: ad_creative_id
- description: >
- The unique identifier for the ad creative that is associated with the ad.
-
- - name: ad_creative_title
+
+ - name: ad_clicks
description: >
- The title of the ad creative used for the ad.
-
+ The number of times the ad was clicked.
+
- name: ad_creative_body
description: >
The body copy of the ad creative used for the ad.
-
+
+ - name: ad_creative_call_to_action_type
+ description: >
+ The type of call-to-action used in the ad creative, such as "order now" or "sign up" (the call to action type will vary by advertising platform).
+
+ - name: ad_creative_facebook_url
+ description: >
+ The URL of the ad creative as it appears on Facebook.
+
+ - name: ad_creative_id
+ description: >
+ The unique identifier for the ad creative that is associated with the ad.
+
- name: ad_creative_image_url
description: >
The URL of the image used in the ad creative.
-
+
+ - name: ad_creative_instagram_url
+ description: >
+ The URL of the ad creative as it appears on Instagram.
+
+ - name: ad_creative_link_params
+ description: >
+ The URL parameters used in the ad creative link.
+
- name: ad_creative_thumbnail_url
description: >
The URL of the thumbnail image used in the ad creative.
-
- - name: ad_creative_call_to_action_type
+
+ - name: ad_creative_title
description: >
- The type of call-to-action used in the ad creative, such as "order now" or "sign up" (the call to action type will vary by advertising platform).
-
- - name: ad_creative_link_params
+ The title of the ad creative used for the ad.
+
+ - name: ad_group_id
description: >
- The URL parameters used in the ad creative link.
-
- - name: ad_creative_instagram_url
+ The unique identifier for the ad group that contains the ad. Used to group related ads within a campaign for organizational and reporting purposes.
+
+ - name: ad_group_name
description: >
- The URL of the ad creative as it appears on Instagram.
-
- - name: ad_creative_facebook_url
+ The name of the ad group that contains the ad. Provides human-readable identification for ad set organization within campaigns.
+
+ - name: ad_id
description: >
- The URL of the ad creative as it appears on Facebook.
+ The unique identifier for the ad.
+
+ - name: ad_impressions
+ description: >
+ The number of times the ad was shown.
+
+ - name: ad_inline_link_clicks
+ description: >
+ The number of clicks on links within the ad that led users to advertiser-specified destinations. Subset of total ad_clicks; excludes non-link engagement clicks (e.g., likes, comments).
+
+ - name: ad_name
+ description: >
+ The name of the ad.
- name: ad_platform_campaign_objective
description: >
The objective of the campaign that is associated with the ad, such as "maximize conversion" or "target impression share" (the campaign objective will vary by advertising platform).
- tests:
- - accepted_values:
- values:
- - manual_cpc
- - landing_page
- - manual_cpm
- - target_cpa
- - target_cpm
- - maximize_conversion_value
- - manual_cpv
- - target_spend
- - maximize_conversions
- - target_roas
- - target_impression_share
- - unknown
+
+ - name: ad_platform_reported_conversion_windows
+ description: >
+ Struct containing platform-reported conversion metrics across different attribution windows. Enables analysis of how attribution window selection affects reported performance.
+
+ - name: ad_platform_reported_conversion_windows.default_window
+ description: >
+ Platform-reported conversions using the default attribution window for the platform (e.g., Meta Ads default blended window).
+
+ - name: ad_platform_reported_conversion_windows._7d_click
+ description: >
+ Platform-reported conversions using a 7-day click attribution window (Meta Ads-specific window).
+
+ - name: ad_platform_reported_conversion_windows._1d_view
+ description: >
+ Platform-reported conversions using a 1-day view attribution window (Meta Ads-specific window).
+
+ - name: ad_platform_reported_conversions
+ description: >
+ The number of conversions attributable to the ad, as reported by the advertising platform.
+
+ - name: ad_platform_reported_revenue
+ description: >
+ The amount of revenue attributable to the ad, as reported by the advertising platform.
+
+ - name: ad_platform_reported_revenue_windows
+ description: >
+ Struct containing platform-reported revenue metrics across different attribution windows. Enables analysis of how attribution window selection affects reported revenue performance.
+
+ - name: ad_platform_reported_revenue_windows.default_window
+ description: >
+ Platform-reported revenue using the default attribution window for the platform (e.g., Meta Ads default blended window).
+
+ - name: ad_platform_reported_revenue_windows._7d_click
+ description: >
+ Platform-reported revenue using a 7-day click attribution window (Meta Ads-specific window).
+
+ - name: ad_platform_reported_revenue_windows._1d_view
+ description: >
+ Platform-reported revenue using a 1-day view attribution window (Meta Ads-specific window).
+
+ - name: ad_spend
+ description: >
+ The amount of money spent on the ad.
- name: date
description: >
The date when the ad was delivered.
-
- - name: ad_id
- description: >
- The unique identifier for the ad.
-
+
- name: sm_channel
description: >
The sales channel associated with the ad.
-
- - name: ad_campaign_tactic
+
+ - name: source_system
description: >
- The tactic of the campaign derived from campaign naming conventions. Possible values are "Prospecting", "Retargeting", and "Brand". Default is "Prospecting".
+ The advertising source system used to deliver the ad.
+
+ - name: sub_channel
+ description: >
+ Sub-channel classification for the ad, typically derived from campaign naming or ad platform specifics. Provides additional granularity beyond sm_channel for channel-specific analysis (e.g., Affiliate, Brand, Retargeting).
- #- name: sm_parent_company_name
- # description: >
- # The name of the parent company that is associated with the SourceMedium smcid.
- #- name: ad_utm_source
- # description: >
- # The UTM source parameter value that is associated with an ad.
- #- name: ad_utm_medium
- # description: >
- # The UTM medium parameter value that is associated with an ad.
- #- name: ad_country_code
- # description: >
- # The ISO 3166-1 alpha-2 country code where the ad was delivered.
- # - name: ad_country
- # description: >
- # The country where the ad was delivered.
- #- name: sm_sub_channel
- # description: >
- # The sub-channel associated with the ad, which, by default, is the name of the advertising platform (the source system).
-
-```
\ No newline at end of file
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters.mdx b/data-activation/data-tables/sm_transformed_v2/rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters.mdx
new file mode 100644
index 0000000..d920f51
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters.mdx
@@ -0,0 +1,194 @@
+---
+title: 'rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters'
+description: 'Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters.'
+icon: "table"
+---
+```yaml
+version: 2
+
+models:
+ - name: rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters
+ description: >
+ Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters).
+ columns:
+ - name: acquisition_order_filter_dimension
+ description: >
+ Dimension name used to group cohorts by first valid purchase attribute (e.g., sm_channel).
+
+ - name: acquisition_order_filter_dimension_value
+ description: >
+ Dimension value for the cohort grouping.
+
+ - name: cohort_filter_name_filter_value_id
+ description: >
+ Unique identifier for the cohort grouping without time dimension (name/value composite).
+
+ - name: cohort_filter_name_filter_value_month_id
+ description: >
+ Unique identifier for the cohort row (name/value/month composite).
+
+ - name: cohort_month
+ description: >
+ Cohort acquisition month.
+
+ - name: cohort_month_gross_profit
+ description: >
+ Total gross profit for the acquisition month only (baseline for cohort profitability calculations).
+
+ - name: cohort_month_order_count
+ description: >
+ Total order count for the acquisition month only (baseline for cohort retention calculations).
+
+ - name: cohort_month_order_gross_revenue
+ description: >
+ Total gross revenue for the acquisition month only (baseline for cohort retention calculations).
+
+ - name: cohort_month_order_net_revenue
+ description: >
+ Total net revenue for the acquisition month only (baseline for cohort retention calculations).
+
+ - name: cohort_month_ordered_quantity
+ description: >
+ Total quantity ordered for the acquisition month only (baseline for cohort retention calculations).
+
+ - name: cohort_month_product_gross_profit
+ description: >
+ Total product gross profit for the acquisition month only (baseline for cohort profitability calculations).
+
+ - name: cohort_size
+ description: >
+ Number of customers in the acquisition cohort.
+
+ - name: cost_per_acquisition
+ description: >
+ Customer acquisition cost for the cohort based on marketing spend.
+
+ - name: cumulative_order_cost_of_returns
+ description: >
+ Running total of return costs from acquisition month through current month offset.
+
+ - name: cumulative_order_count
+ description: >
+ Running total of orders from acquisition month through current month offset.
+
+ - name: cumulative_order_fulfillment_cost
+ description: >
+ Running total of fulfillment costs from acquisition month through current month offset.
+
+ - name: cumulative_order_gross_profit
+ description: >
+ Running total of gross profit from acquisition month through current month offset.
+
+ - name: cumulative_order_gross_revenue
+ description: >
+ Running total of gross revenue from acquisition month through current month offset.
+
+ - name: cumulative_order_merchant_processing_fees
+ description: >
+ Running total of payment processing fees from acquisition month through current month offset.
+
+ - name: cumulative_order_net_revenue
+ description: >
+ Running total of net revenue from acquisition month through current month offset for LTV calculation.
+
+ - name: cumulative_order_net_shipping
+ description: >
+ Running total of net shipping revenue from acquisition month through current month offset.
+
+ - name: cumulative_order_product_cost
+ description: >
+ Running total of product costs from acquisition month through current month offset.
+
+ - name: cumulative_order_shipping_cost
+ description: >
+ Running total of shipping costs from acquisition month through current month offset.
+
+ - name: cumulative_ordered_quantiy
+ description: >
+ Running total of items ordered from acquisition month through current month offset.
+
+ - name: cumulative_product_gross_profit
+ description: >
+ Running total of product gross profit from acquisition month through current month offset.
+
+ - name: cumulative_second_order_count
+ description: >
+ Running count of customers who have placed a second order through current month offset.
+
+ - name: cumulative_third_order_count
+ description: >
+ Running count of customers who have placed a third order through current month offset.
+
+ - name: customer_count
+ description: >
+ Number of distinct customers with orders in the month offset period.
+
+ - name: months_since_first_order
+ description: >
+ Numeric offset from acquisition month (0 = acquisition month, 1 = month +1, etc.).
+
+ - name: months_since_first_order_name
+ description: >
+ Label for months since first valid purchase (e.g., 'Acquisition Month', '+1').
+
+ - name: order_cost_of_returns
+ description: >
+ Cost of returns processed in the month offset period.
+
+ - name: order_count
+ description: >
+ Number of orders placed in the month offset period.
+
+ - name: order_fulfillment_cost
+ description: >
+ Fulfillment and handling costs for orders in the month offset period.
+
+ - name: order_gross_profit
+ description: >
+ Total gross profit including all costs for orders in the month offset period.
+
+ - name: order_gross_revenue
+ description: >
+ Gross revenue before discounts and refunds for orders in the month offset period.
+
+ - name: order_merchant_processing_fees
+ description: >
+ Payment processing fees for orders in the month offset period.
+
+ - name: order_net_revenue
+ description: >
+ Net revenue after discounts and refunds for orders in the month offset period.
+
+ - name: order_product_cost
+ description: >
+ Product cost (COGS) for orders in the month offset period.
+
+ - name: order_product_gross_profit
+ description: >
+ Product gross profit (revenue minus product cost) for orders in the month offset period.
+
+ - name: order_shipping
+ description: >
+ Net shipping revenue (charged to customers) for orders in the month offset period.
+
+ - name: order_shipping_cost
+ description: >
+ Shipping cost incurred for orders in the month offset period.
+
+ - name: ordered_quantity
+ description: >
+ Total quantity of items ordered in the month offset period.
+
+ - name: sm_channel
+ description: >
+ Acquisition channel for cohort segmentation (mapped from channel field in parent model).
+
+ - name: sm_order_line_type
+ description: >
+ Order line type segmentation (mapped from slice field in parent model).
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily.mdx b/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily.mdx
index ca9c070..4182302 100644
--- a/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily.mdx
+++ b/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily.mdx
@@ -1,322 +1,242 @@
---
title: 'rpt_executive_summary_daily'
-description: ''
+description: 'Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets).'
+icon: "table"
---
-
```yaml
version: 2
models:
- name: rpt_executive_summary_daily
description: >
- The rpt_executive_summary_daily table is a report table containing daily aggregated metrics across all of the data sources
- integrated with SourceMedium. This includes key metrics from your advertising, e-commerce, subscription, and analytics data sources
- at date-level granularity. This report (RPT) table is optimized for a BI tool's consumption.
-
+ Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (sm_store_id, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters.
columns:
- - name: date
- description: >
- The date in YYYY-MM-DD format.
- tests:
- - not_null
-
- - name: smcid
- description: >
- The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
- tests:
- - not_null
-
- - name: sm_master_account_id
- description: >
- The unique identifier for the master account that is associated with the SourceMedium smcid.
-
- - name: store_name
- description: >
- The name of the store that is associated with the SourceMedium smcid.
-
- - name: sm_channel
- description: >
- The channel associated with the data, which is derived from the source system (e-commerce or advertising platform) and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
- tests:
- - not_null
-
- - name: order_count
- description: >
- The number of orders placed by customers.
-
- - name: order_gross_revenue
- description: >
- The gross revenue for orders, based on order lines. Gross revenue is calculated by multiplying the price of an order's lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
-
- - name: order_net_revenue
- description: >
- The gross order revenue minus order discounts and refunds.
-
- - name: order_total_revenue
- description: >
- Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
-
- - name: order_discounts
- description: >
- The total amount of discounts applied to orders.
-
- - name: order_refunds
- description: >
- The total amount of refunds applied to orders.
-
- - name: order_net_shipping
- description: >
- The gross shipping revenue for orders minus shipping discounts and shipping refunds.
-
- - name: order_total_taxes
- description: >
- The amount of order and shipping taxes minus order and shipping tax refunds.
-
- - name: order_shipping_cost
- description: >
- The blended cost to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
-
- - name: order_return_cost
- description: >
- The blended cost to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
-
- - name: order_fulfillment_cost
- description: >
- The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
-
- - name: order_merchant_processing_fees
- description: >
- The payment processing fees for orders. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
-
- - name: order_product_cost
- description: >
- The landed cost of orders as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify.
-
- - name: product_gross_profit
- description: >
- Net order line revenue minus product cost.
-
- - name: gross_profit
- description: >
- Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
-
- - name: operating_expenses
- description: >
- The cost the business incurs while performing its normal operational activities. This data is entered into the Financial Cost - Operating Expenses tab of the SourceMedium financial cost configuration sheet.
-
- - name: ad_spend
- description: >
- The amount of money spent on ads.
-
- - name: ad_clicks
- description: >
- The number of times ads were clicked.
-
- - name: ad_impressions
- description: >
- The number of times ads were shown.
-
- - name: ad_platform_reported_conversions
- description: >
- The number of conversions attributable to ads, as reported by the advertising platform.
-
- - name: ad_platform_reported_revenue
- description: >
- The amount of revenue attributable to the ads, as reported by the advertising platform.
-
- - name: website_sessions
- description: >
- The number of sessions on the website.
-
- - name: new_subscription_count
- description: >
- The number of new subscriptions started by customers.
-
- - name: cancelled_subscription_count
- description: >
- The number of subscriptions voluntarily cancelled by customers.
-
- - name: cancelled_passive_subscription_count
- description: >
- The number of subscriptions that were terminated without active customer initiation, often due to reasons like the natural expiration of the subscription period.
-
- - name: new_subscription_monthly_recurring_revenue
- description: >
- Monthly recurring revenue associated with new subscriptions, normalized to a standard month (30.437 days).
-
- - name: cancelled_subscription_monthly_recurring_revenue
- description: >
- Monthly recurring revenue associated with cancelled subscriptions, normalized to a standard month (30.437 days).
-
- - name: cancelled_passive_subscription_monthly_recurring_revenue
- description: >
- Monthly recurring revenue associated with passively cancelled subscriptions, normalized to a standard month (30.437 days).
-
- - name: active_subscription_count
- description: >
- The number of active subscriptions with a store.
-
- - name: churned_subscription_count
- description: >
- The cumulative number of subscriptions that have been cancelled.
-
- - name: subscription_monthly_recurring_revenue
- description: >
- Monthly recurring revenue associated with active subscriptions, normalized to a standard "month" (30.437 days).
-
- - name: dunning_subscription_count
- description: >
- The number of subscriptions that are in dunning, which is the process of communicating with customers to collect payment for a subscription that is past due.
-
- - name: new_subscriber_count
- description: >
- The number of customers who converted on their first subscription program.
-
- - name: cancelled_subscriber_count
- description: >
- The number of customers who cancelled their final subscription (they do not have any active subscriptions).
-
- - name: active_subscriber_count
- description: >
- The number of customers who have at least one active subscription.
-
- - name: new_dunning_subscriber_count
- description: >
- The number of customers who entered into dunning.
-
- - name: churned_subscriber_count
- description: >
- The cumulative number of customers who have cancelled their final subscription.
-
- - name: customer_count
- description: >
- The number of unique customers who made a purchase.
-
- - name: new_customer_count
- description: >
- The number of unique customers who made their first purchase.
-
- - name: repeat_customer_count
- description: >
- The number of unique customers who made at least their second purchase.
-
- - name: new_customer_order_net_revenue
- description: >
- The net order revenue from new customers.
-
- - name: repeat_customer_order_net_revenue
- description: >
- The net order revenue from repeat customers.
-
- - name: new_customer_order_gross_revenue
- description: >
- The gross order revenue from new customers.
-
- - name: repeat_customer_order_gross_revenue
- description: >
- The gross order revenue from repeat customers.
-
- - name: new_customer_order_count
- description: >
- The number of orders from new customers.
-
- - name: repeat_customer_order_count
- description: >
- The number of orders from repeat customers.
-
- - name: week_start_date
- description: >
- The starting date of the week in YYYY-MM-DD format.
-
- - name: month_start_date
- description: >
- The starting date of the month in YYYY-MM-DD format.
-
- - name: quarter_start_date
- description: >
- The starting date of the quarter in YYYY-MM-DD format.
-
- - name: year_start_date
- description: >
- The starting date of the year in YYYY-MM-DD format.
-
- - name: order_net_revenue_before_refunds
- description: >
- The gross order revenue minus order discounts.
-
- - name: target_order_gross_revenue
- description: >
- The gross order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_order_net_revenue
- description: >
- The net order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_total_order_revenue
- description: >
- The total order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_order_count
- description: >
- The order count target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_ad_spend
- description: >
- The ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_website_sessions
- description: >
- The website sessions target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_average_order_value
- description: >
- The average order value target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_cost_per_acquisition
- description: >
- The cost per acquisition target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_return_on_ad_spend
- description: >
- The return on ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: target_order_conversion_rate
- description: >
- The order conversion rate target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
-
- - name: contribution_profit
- description: >
- Gross profit minus ad spend.
-
- - name: net_profit
- description: >
- Gross profit minus ad spend and operating expenses.
-
- #- name: sm_parent_company_name
- # description: >
- # The name of the parent company that is associated with the SourceMedium smcid.
-
- #- name: country
- # description: >
- # The country associated with the data.
-
- #- name: country_code
- # description: >
- # The ISO 3166-1 alpha-2 country code.
-
- #- name: sm_sub_channel
- # description: >
- # The sub-channel associated with the data, which is derived from the source system (e-commerce or advertising platform) and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet.
-
- #- name: non_recurring_order_net_revenue
- # description: >
- # The net order revenue from regular one-time purchases.
-
- #- name: non_recurring_order_gross_revenue
- # description: >
- # The gross order revenue from non-recurring subscriptions.
-
- #- name: non_recurring_order_count
- # description: >
- # The number of orders from non-recurring subscriptions.
- ```
\ No newline at end of file
+ - name: active_subscriber_count
+ description: >
+ The number of customers who have at least one active subscription.
+
+ - name: active_subscription_count
+ description: >
+ The number of active subscriptions with a store.
+
+ - name: ad_clicks
+ description: >
+ The number of times ads were clicked.
+
+ - name: ad_impressions
+ description: >
+ The number of times ads were shown.
+
+ - name: ad_platform_reported_conversions
+ description: >
+ The number of conversions attributable to ads, as reported by the advertising platform.
+
+ - name: ad_platform_reported_revenue
+ description: >
+ The amount of revenue attributable to the ads, as reported by the advertising platform.
+
+ - name: ad_spend
+ description: >
+ The amount of money spent on ads.
+
+ - name: cancelled_passive_subscription_count
+ description: >
+ The number of subscriptions that were terminated without active customer initiation, often due to reasons like the natural expiration of the subscription period.
+
+ - name: cancelled_subscriber_count
+ description: >
+ The number of customers who cancelled their final subscription (they do not have any active subscriptions).
+
+ - name: cancelled_subscription_count
+ description: >
+ The number of subscriptions voluntarily cancelled by customers.
+
+ - name: cancelled_subscriber_count_daily_snapshot
+ description: >
+ The cumulative number of customers who have cancelled their final subscription (daily snapshot).
+
+ - name: cancelled_subscription_count_daily_snapshot
+ description: >
+ The cumulative number of subscriptions that have been cancelled (daily snapshot).
+
+ - name: contribution_profit
+ description: >
+ Gross profit minus ad spend.
+
+ - name: customer_count
+ description: >
+ The number of unique customers who made a purchase.
+
+ - name: date
+ description: >
+ The date in YYYY-MM-DD format.
+
+ - name: gross_profit
+ description: >
+ Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees.
+
+ - name: net_profit
+ description: >
+ Gross profit minus ad spend and operating expenses.
+
+ - name: new_customer_count
+ description: >
+ The number of unique customers who made their first purchase. Special Considerations: Platform coverage varies; tests allow for low coverage thresholds in some cases.
+
+ - name: new_customer_order_count
+ description: >
+ The number of orders from new customers.
+
+ - name: new_customer_order_gross_revenue
+ description: >
+ The gross order revenue from new customers.
+
+ - name: new_customer_order_net_revenue
+ description: >
+ The net order revenue from new customers.
+
+ - name: new_subscriber_count
+ description: >
+ The number of customers who converted on their first subscription program.
+
+ - name: new_subscription_count
+ description: >
+ The number of new subscriptions started by customers.
+
+ - name: operating_expenses
+ description: >
+ The cost the business incurs while performing its normal operational activities. This data is entered into the Financial Cost - Operating Expenses tab of the SourceMedium financial cost configuration sheet.
+
+ - name: order_count
+ description: >
+ The number of orders placed by customers.
+
+ - name: order_discounts
+ description: >
+ The total amount of discounts applied to orders.
+
+ - name: order_fulfillment_cost
+ description: >
+ The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet.
+
+ - name: order_gross_revenue
+ description: >
+ The gross revenue for orders, based on order lines. Gross revenue is calculated by multiplying the price of an order's lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases.
+
+ - name: order_gross_revenue_after_discounts
+ description: >
+ The gross order revenue minus order discounts.
+
+ - name: order_merchant_processing_fees
+ description: >
+ The payment processing fees for orders. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet.
+
+ - name: order_net_revenue
+ description: >
+ The gross order revenue minus order discounts and refunds.
+
+ - name: order_net_shipping_revenue
+ description: >
+ The gross shipping revenue for orders minus shipping discounts and shipping refunds.
+
+ - name: order_product_cost
+ description: >
+ The landed cost of orders as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify.
+
+ - name: order_refunds
+ description: >
+ The total amount of refunds applied to orders.
+
+ - name: order_return_cost
+ description: >
+ The blended cost to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+
+ - name: order_shipping_cost
+ description: >
+ The blended cost to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet.
+
+ - name: order_total_revenue
+ description: >
+ Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds.
+
+ - name: order_total_taxes
+ description: >
+ The amount of order and shipping taxes minus order and shipping tax refunds.
+
+ - name: product_gross_profit
+ description: >
+ Net order line revenue minus product cost.
+
+ - name: repeat_customer_count
+ description: >
+ The number of unique customers who made at least their second purchase.
+
+ - name: repeat_customer_order_count
+ description: >
+ The number of orders from repeat customers.
+
+ - name: repeat_customer_order_gross_revenue
+ description: >
+ The gross order revenue from repeat customers. Special Considerations: Platform aggregation rules can differ; see tests for permitted thresholds.
+
+ - name: repeat_customer_order_net_revenue
+ description: >
+ The net order revenue from repeat customers.
+
+ - name: sm_channel
+ description: >
+ Sales channel via hierarchy: (1) exclusion tag 'sm-exclude-order' -> excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -> retail, wholesale tags -> wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: sm_sub_channel
+ description: >
+ Sub-channel from source/tags with config overrides (e.g., Facebook & Instagram, Google, Amazon FBA/Fulfilled by Merchant).
+
+ - name: target_ad_spend
+ description: >
+ The ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_average_order_value
+ description: >
+ The average order value target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_customer_acquisition_cost
+ description: >
+ The customer acquisition cost target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_order_conversion_rate
+ description: >
+ The order conversion rate target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_order_count
+ description: >
+ The order count target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_order_gross_revenue
+ description: >
+ The gross order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_order_net_revenue
+ description: >
+ The net order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_return_on_ad_spend
+ description: >
+ The return on ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_total_order_revenue
+ description: >
+ The total order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: target_website_sessions
+ description: >
+ The website sessions target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet.
+
+ - name: website_sessions
+ description: >
+ The number of sessions on the website.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/rpt_funnel_events_performance_hourly.mdx b/data-activation/data-tables/sm_transformed_v2/rpt_funnel_events_performance_hourly.mdx
new file mode 100644
index 0000000..a0ab256
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/rpt_funnel_events_performance_hourly.mdx
@@ -0,0 +1,118 @@
+---
+title: 'rpt_funnel_events_performance_hourly'
+description: 'Hourly funnel event aggregation for monitoring funnel volumes and event-based ratios (directional).'
+icon: "table"
+---
+```yaml
+version: 2
+
+models:
+ - name: rpt_funnel_events_performance_hourly
+ description: >
+ Hourly funnel event aggregation for monitoring funnel volumes and event-based ratios (directional). Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. Note: This table is aggregated at the event level. Ratios computed from *_event_count columns are event-based and directional (not distinct-session conversion rates).
+ columns:
+ - name: account_sign_up_event_count
+ description: >
+ Count of account registration events within the hour.
+
+ - name: add_payment_info_event_count
+ description: >
+ Count of payment information submission events within the hour.
+
+ - name: add_shipping_info_event_count
+ description: >
+ Count of shipping information submission events within the hour.
+
+ - name: add_to_cart_event_count
+ description: >
+ Count of add-to-cart events within the hour for funnel analysis.
+
+ - name: begin_checkout_event_count
+ description: >
+ Count of checkout initiation events within the hour for conversion funnel tracking.
+
+ - name: email_sign_up_event_count
+ description: >
+ Count of email subscription and lead generation events (subscribe, generate_lead) within the hour.
+
+ - name: event_local_datetime
+ description: >
+ Event timestamp in the reporting time zone (hourly bucket).
+
+ - name: event_order_revenue
+ description: >
+ Total revenue attributed to events within the hour aggregated from event_order_revenue field.
+
+ - name: event_page_path
+ description: >
+ URL path component for page-level aggregation.
+
+ - name: event_page_title
+ description: >
+ Page title where the event occurred for content analysis.
+
+ - name: event_page_url
+ description: >
+ Page URL without query parameters where the event occurred.
+
+ - name: event_utm_campaign
+ description: >
+ UTM campaign parameter for campaign-level attribution.
+
+ - name: event_utm_content
+ description: >
+ UTM content parameter for A/B testing and ad variation tracking.
+
+ - name: event_utm_medium
+ description: >
+ UTM medium parameter for channel grouping (e.g., cpc, social, email).
+
+ - name: event_utm_source
+ description: >
+ UTM source parameter for attribution analysis (e.g., google, facebook, email).
+
+ - name: event_utm_term
+ description: >
+ UTM term parameter for paid search keyword tracking.
+
+ - name: page_view_event_count
+ description: >
+ Count of page view events within the hour for traffic analysis.
+
+ - name: purchase_event_count
+ description: >
+ Count of purchase events within the hour.
+
+ - name: refund_event_count
+ description: >
+ Count of refund events within the hour.
+
+ - name: remove_from_cart_event_count
+ description: >
+ Count of cart removal events within the hour.
+
+ - name: select_item_event_count
+ description: >
+ Count of product selection events within the hour.
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: source_system
+ description: >
+ Tracking platform emitting the event (elevar, blotout, snowplow, snowplow_ga4, heap, ga4).
+
+ - name: view_cart_event_count
+ description: >
+ Count of cart page view events within the hour.
+
+ - name: view_item_event_count
+ description: >
+ Count of product detail page view events within the hour.
+
+ - name: view_item_list_event_count
+ description: >
+ Count of product listing page view events within the hour.
+
+```
diff --git a/data-activation/data-tables/sm_transformed_v2/rpt_outbound_message_performance_daily.mdx b/data-activation/data-tables/sm_transformed_v2/rpt_outbound_message_performance_daily.mdx
new file mode 100644
index 0000000..2a60dfb
--- /dev/null
+++ b/data-activation/data-tables/sm_transformed_v2/rpt_outbound_message_performance_daily.mdx
@@ -0,0 +1,118 @@
+---
+title: 'rpt_outbound_message_performance_daily'
+description: 'Daily messaging performance across email/SMS/push for campaigns and flows.'
+icon: "table"
+---
+```yaml
+version: 2
+
+models:
+ - name: rpt_outbound_message_performance_daily
+ description: >
+ Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters.
+ columns:
+ - name: campaign_id
+ description: >
+ Messaging campaign identifier (if message_type is campaign).
+
+ - name: campaign_name
+ description: >
+ Messaging campaign name (if message_type is campaign).
+
+ - name: sm_channel
+ description: >
+ Sales channel for the message performance (always 'Online DTC' for email/SMS/push campaigns). Provides consistency with order-level channel attribution in multi-channel reporting.
+
+ - name: date
+ description: >
+ Calendar date for daily aggregation.
+
+ - name: dimension_value
+ description: >
+ Dimension grouping value (e.g., campaign or flow identifier) depending on report mode.
+
+ - name: list_subscribes
+ description: >
+ Count of list subscription events attributed to the message.
+
+ - name: list_unsubscribes
+ description: >
+ Count of list unsubscribe events attributed to the message.
+
+ - name: message_id
+ description: >
+ Platform message identifier for the send.
+
+ - name: message_name
+ description: >
+ The name/title of the message as configured in the messaging platform. Used to identify specific email templates, SMS messages, or push notifications.
+
+ - name: message_subject
+ description: >
+ The subject line of the message (primarily for email campaigns). NULL for SMS/push messages that don't have subject lines.
+
+ - name: message_type
+ description: >
+ Whether the message originated from a flow/automation or from a campaign send.
+
+ - name: message_unique_bounces
+ description: >
+ Count of unique bounces.
+
+ - name: message_unique_clicks
+ description: >
+ Count of unique clicks.
+
+ - name: message_unique_drops
+ description: >
+ Count of unique drops/suppressed sends.
+
+ - name: message_unique_opens
+ description: >
+ Count of unique opens.
+
+ - name: message_unique_receives
+ description: >
+ Count of unique receives/deliveries.
+
+ - name: platform_reported_begin_checkout_revenue
+ description: >
+ Platform-attributed revenue from begin checkout events.
+
+ - name: platform_reported_begin_checkouts
+ description: >
+ Platform-attributed begin checkout events from the message/day.
+
+ - name: platform_reported_order_line_quantity
+ description: >
+ Platform-attributed order line item quantity from the message/day.
+
+ - name: platform_reported_order_line_revenue
+ description: >
+ Platform-attributed order line revenue from the message/day.
+
+ - name: platform_reported_order_revenue
+ description: >
+ Platform-attributed order revenue from the message/day.
+
+ - name: platform_reported_orders
+ description: >
+ Platform-attributed order conversions from the message/day.
+
+ - name: sm_message_channel
+ description: >
+ Normalized message channel (email, sms, push).
+
+ - name: sm_store_id
+ description: >
+ SourceMedium's unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.
+
+ - name: sms_unique_sends
+ description: >
+ Count of unique SMS sends for the message/day.
+
+ - name: source_system
+ description: >
+ The messaging platform that sent the message (e.g., Klaviyo, Postscript, Attentive). Used to segment performance by messaging service provider.
+
+```
diff --git a/data-activation/managed-bi-v1/core-dashboard-features.mdx b/data-activation/managed-bi-v1/core-dashboard-features.mdx
index 751ecce..32b3cc9 100644
--- a/data-activation/managed-bi-v1/core-dashboard-features.mdx
+++ b/data-activation/managed-bi-v1/core-dashboard-features.mdx
@@ -1,6 +1,7 @@
---
title: "Core Dashboard Features"
description: "Let's explore some of the basic features that allow your team to quickly navigate your data within SourceMedium:"
+icon: "chart-line"
---
@@ -132,4 +133,4 @@ If you would like to share the SourceMedium Dashboard with a coworker, **they mu
Once a new member has been added to your SourceMedium access group, you will now be able to share specific views of any dashboard module with all filters intact!
-
\ No newline at end of file
+
diff --git a/data-activation/managed-bi-v1/modules/emails-conversions-module.mdx b/data-activation/managed-bi-v1/modules/emails-conversions-module.mdx
index 5f36900..c9d577b 100644
--- a/data-activation/managed-bi-v1/modules/emails-conversions-module.mdx
+++ b/data-activation/managed-bi-v1/modules/emails-conversions-module.mdx
@@ -1,9 +1,9 @@
---
title: "The Emails - Conversions Module"
+description: "Overview of the The Emails - Conversions Module module and how to use it."
sidebarTitle: "Emails - Conversions"
icon: 'envelope-open-text'
---
-
#### What is the Emails - General module and what data can be found there?
- This module reports on email conversions. This module is based on the UTM tracking parameters from you commerce platform / Google Analytics.
- This is where you will be able to explore which email campaigns are driving conversions.
diff --git a/data-activation/managed-bi-v1/modules/emails-general-module.mdx b/data-activation/managed-bi-v1/modules/emails-general-module.mdx
index 2b4b125..22501b9 100644
--- a/data-activation/managed-bi-v1/modules/emails-general-module.mdx
+++ b/data-activation/managed-bi-v1/modules/emails-general-module.mdx
@@ -1,11 +1,11 @@
---
title: "The Emails - General Module"
+description: "Overview of the The Emails - General Module module and how to use it."
sidebarTitle: "Emails - General"
icon: 'envelope-open-text'
---
-
#### What is the Emails - General module and what data can be found there?
-This module integrates your email marketing platforms such as Klaviyo, HubSpot, Mailchimp, Autopilot, etc. Source Medium ingests the email marketing data based on your largest list / segment. It allows a deep dive into your email marketing performance.
+This module integrates your email marketing platforms such as Klaviyo, HubSpot, Autopilot, etc. SourceMedium ingests the email marketing data based on your largest list / segment. It allows a deep dive into your email marketing performance.
#### Common Questions & Insights That Can Be Answered Here:
@@ -26,4 +26,4 @@ This can be found in the **Email Performance Vitals** chart and the **Open, Clic
#### Potential Reporting Differences & Discrepancies
-SourceMedium ingests the email marketing data based on your largest list / segment.
\ No newline at end of file
+SourceMedium ingests the email marketing data based on your largest list / segment.
diff --git a/data-activation/managed-bi-v1/modules/executive-summary-module.mdx b/data-activation/managed-bi-v1/modules/executive-summary-module.mdx
index 359cf02..7ca13b9 100644
--- a/data-activation/managed-bi-v1/modules/executive-summary-module.mdx
+++ b/data-activation/managed-bi-v1/modules/executive-summary-module.mdx
@@ -1,9 +1,9 @@
---
title: "The Executive Summary Module"
+description: "Overview of the The Executive Summary Module module and how to use it."
sidebarTitle: "Executive Summary"
icon: 'globe'
---
-
@@ -30,8 +30,8 @@ icon: 'globe'
The Executive Summary is designed to mirror the accounting rules present in the Shopify Sales Report, and will almost always match 1:1. However, there are some instances where you won't see a 1:1 match:
1. If your brand has our 'Exclude \$0 Orders' feature enabled, you will see a revenue and orders mismatch. This feature excludes orders with a total revenue of \$0 from all Executive Summary and Retention dashboard data. If you're unsure if you have this feature enabled, reach out to our Support team in Slack or via email at [help@sourcemedium.com](mailto:help@sourcemedium.com).
- - [See here for a deeper explanation of this feature.](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature)
+ - [See here for a deeper explanation of this feature.](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
2. If your brand has any data cleaning rules in the Channel Mapping tab your Configuration Sheet *(e.g. any rules routing orders to a channel other than Online DTC)* you will see a mismatch if only Online DTC is selected in the channel dropdown (located at the top right-hand corner of your report, under the date range filter).
- **If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between the Executive Summary and Shopify Sales report.**
\ No newline at end of file
+ **If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between the Executive Summary and Shopify Sales report.**
diff --git a/data-activation/managed-bi-v1/modules/google-ads-module.mdx b/data-activation/managed-bi-v1/modules/google-ads-module.mdx
index 48d9304..099de5f 100644
--- a/data-activation/managed-bi-v1/modules/google-ads-module.mdx
+++ b/data-activation/managed-bi-v1/modules/google-ads-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Google Ads Module"
+description: "Overview of the The Google Ads Module module and how to use it."
sidebarTitle: "Google Ads"
icon: 'google'
---
diff --git a/data-activation/managed-bi-v1/modules/google-search-console-module.mdx b/data-activation/managed-bi-v1/modules/google-search-console-module.mdx
index 4c53529..bc2970b 100644
--- a/data-activation/managed-bi-v1/modules/google-search-console-module.mdx
+++ b/data-activation/managed-bi-v1/modules/google-search-console-module.mdx
@@ -1,10 +1,11 @@
---
title: "The Google Search Console Module"
+description: "Overview of the The Google Search Console Module module and how to use it."
sidebarTitle: "Google Search Console"
icon: 'user-secret'
---
#### What is the Google Search Console module and what data can be found there?
-This module directly connects to your Google Search Console. The data seen in this module does not enter into the Source Medium data model and is not available outside this module.
+This module directly connects to your Google Search Console. The data seen in this module does not enter into the SourceMedium data model and is not available outside this module.
#### Common Questions & Insights That Can Be Answered Here:
diff --git a/data-activation/managed-bi-v1/modules/hidden-videos-code-dashboard-features.mdx b/data-activation/managed-bi-v1/modules/hidden-videos-code-dashboard-features.mdx
deleted file mode 100644
index f6c9d81..0000000
--- a/data-activation/managed-bi-v1/modules/hidden-videos-code-dashboard-features.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
-Welcome Embedded
-
-
-
-
-
-- How do you Drill Up / Drill Down on the date?
- - Embedded link1:
- - Embedded link2:
-- How can you toggle between Channels within the SourceMedium Dashboard?
- - Embedded link1:
- - Embedded link2:
diff --git a/data-activation/managed-bi-v1/modules/index.mdx b/data-activation/managed-bi-v1/modules/index.mdx
new file mode 100644
index 0000000..202eb36
--- /dev/null
+++ b/data-activation/managed-bi-v1/modules/index.mdx
@@ -0,0 +1,133 @@
+---
+title: "Dashboard Modules Overview"
+sidebarTitle: "Modules Overview"
+description: "Guide to all available modules in your SourceMedium dashboard and what insights each provides"
+icon: "grid-2"
+---
+
+## What Are Modules?
+
+Modules are pre-built analysis views within your SourceMedium dashboard. Each module focuses on a specific area of your business—marketing performance, customer behavior, product analytics, and more.
+
+
+Not all modules may be enabled for your account. Contact your SourceMedium team to activate additional modules.
+
+
+---
+
+## Executive & Overview
+
+
+
+ High-level business KPIs: revenue, orders, customers, and marketing efficiency metrics.
+
+
+ Year-over-year comparisons to track growth and seasonality.
+
+
+
+---
+
+## Marketing Performance
+
+
+
+ Cross-channel marketing performance with spend, ROAS, and attribution data.
+
+
+ Facebook and Instagram advertising performance deep dive.
+
+
+ Google Ads campaign, ad group, and keyword performance.
+
+
+ Organic search performance, queries, and click-through rates.
+
+
+ Influencer and affiliate marketing performance tracking.
+
+
+
+---
+
+## Traffic & Funnel
+
+
+
+ Website traffic sources, sessions, and conversion funnel analysis.
+
+
+
+---
+
+## Email & SMS
+
+
+
+ Email campaign performance: sends, opens, clicks, and engagement.
+
+
+ Email-attributed revenue and conversion metrics.
+
+
+
+---
+
+## Customer Analytics
+
+
+
+ Customer lifetime value, retention curves, and cohort analysis.
+
+
+ Repeat purchase behavior, time between orders, and repurchase rates.
+
+
+ First-time customer acquisition channels and behavior.
+
+
+ Analysis of customers' most recent purchases.
+
+
+
+---
+
+## Orders & Products
+
+
+
+ Order-level analysis with filtering by channel, product, and customer segment.
+
+
+ Product and variant sales, margins, and inventory performance.
+
+
+ Products frequently purchased together and cross-sell opportunities.
+
+
+
+---
+
+## Subscriptions
+
+
+
+ Subscription revenue, churn, and subscriber lifecycle metrics.
+
+
+ Performance of individual subscription products and plans.
+
+
+
+---
+
+## Related Resources
+
+
+
+ Learn about filters, date ranges, and dashboard controls.
+
+
+ Explore the underlying data tables powering these modules.
+
+
diff --git a/data-activation/managed-bi-v1/modules/influencers-deep-dive-module.mdx b/data-activation/managed-bi-v1/modules/influencers-deep-dive-module.mdx
index ba942a7..7654805 100644
--- a/data-activation/managed-bi-v1/modules/influencers-deep-dive-module.mdx
+++ b/data-activation/managed-bi-v1/modules/influencers-deep-dive-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Influencers Deep Dive Module"
+description: "Overview of the The Influencers Deep Dive Module module and how to use it."
sidebarTitle: "Influencers Deep Dive"
icon: 'people-arrows'
---
@@ -27,4 +28,4 @@ This can be found in the **Performance by Discount Code** chart
Spend is amortized over the time period entered in the Configuration Sheet.
-
\ No newline at end of file
+
diff --git a/data-activation/managed-bi-v1/modules/last-order-analysis-module.mdx b/data-activation/managed-bi-v1/modules/last-order-analysis-module.mdx
index 9d18f09..305151c 100644
--- a/data-activation/managed-bi-v1/modules/last-order-analysis-module.mdx
+++ b/data-activation/managed-bi-v1/modules/last-order-analysis-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Last Order Analysis Module"
+description: "Overview of the The Last Order Analysis Module module and how to use it."
sidebarTitle: "Customers -> Last Order Analysis"
icon: 'magnifying-glass'
---
@@ -25,4 +26,4 @@ The Last Order Analysis populates data from your online store(s), subscription p
#### Potential Reporting Differences & Discrepancies
-Customers are surfaced whose last order is within the dates selected in the date range filter and can be first time orders and/or repeat orders.
\ No newline at end of file
+Customers are surfaced whose last order is within the dates selected in the date range filter and can be first time orders and/or repeat orders.
diff --git a/data-activation/managed-bi-v1/modules/ltv-retention-module.mdx b/data-activation/managed-bi-v1/modules/ltv-retention-module.mdx
index 4a90e44..a4fba10 100644
--- a/data-activation/managed-bi-v1/modules/ltv-retention-module.mdx
+++ b/data-activation/managed-bi-v1/modules/ltv-retention-module.mdx
@@ -1,5 +1,6 @@
---
title: "The LTV & Retention Module"
+description: "Overview of the The LTV & Retention Module module and how to use it."
sidebarTitle: "LTV & Retention"
icon: 'recycle'
---
@@ -26,4 +27,4 @@ icon: 'recycle'
- Defaulted to **Net Revenue**
- Filters (order type, sub-channel, etc.) apply to customers' **acquisition order**
- Cohorts based on `order_process` date when the order is at least partially paid
- - If we do not have a direct integration with a subscription platform, we rely on tags to determine subscription vs. non-subscription order type
\ No newline at end of file
+ - If we do not have a direct integration with a subscription platform, we rely on tags to determine subscription vs. non-subscription order type
diff --git a/data-activation/managed-bi-v1/modules/marketing-overview-module.mdx b/data-activation/managed-bi-v1/modules/marketing-overview-module.mdx
index 60c2a10..eb3e367 100644
--- a/data-activation/managed-bi-v1/modules/marketing-overview-module.mdx
+++ b/data-activation/managed-bi-v1/modules/marketing-overview-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Marketing Overview Module"
+description: "Overview of the The Marketing Overview Module module and how to use it."
sidebarTitle: "Marketing Overview"
icon: 'bullhorn'
---
@@ -25,4 +26,4 @@ icon: 'bullhorn'
#### Potential Reporting Differences & Discrepancies
- For Meta, SourceMedium reports on an account-level default of 7-day click, 1-day view. If you are looking at different attribution windows within the Meta UI it will look like there is a discrepancy in reporting vs. the SourceMedium dashboard.
- - SourceMedium separates **Campaign Types** based on common Campaign naming conventions, which can be modified if our logic does not pick up the correct categorization.
\ No newline at end of file
+ - SourceMedium separates **Campaign Types** based on common Campaign naming conventions, which can be modified if our logic does not pick up the correct categorization.
diff --git a/data-activation/managed-bi-v1/modules/meta-ads-module.mdx b/data-activation/managed-bi-v1/modules/meta-ads-module.mdx
index b959564..d5b8a67 100644
--- a/data-activation/managed-bi-v1/modules/meta-ads-module.mdx
+++ b/data-activation/managed-bi-v1/modules/meta-ads-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Meta Ads Module"
+description: "Overview of the The Meta Ads Module module and how to use it."
sidebarTitle: "Meta Ads"
icon: 'meta'
---
@@ -27,4 +28,4 @@ This can be found in the **Performance by Date & Campaign** table and the **Perf
#### Potential Reporting Differences & Discrepancies
-SourceMedium reports Meta data on an account-level default of 7-day click, 1-day view. If different attribution windows are set between campaigns, this can cause confusion when validating vs. the Meta UI.
\ No newline at end of file
+SourceMedium reports Meta data on an account-level default of 7-day click, 1-day view. If different attribution windows are set between campaigns, this can cause confusion when validating vs. the Meta UI.
diff --git a/data-activation/managed-bi-v1/modules/module-overview-template.mdx b/data-activation/managed-bi-v1/modules/module-overview-template.mdx
deleted file mode 100644
index 43f4e5f..0000000
--- a/data-activation/managed-bi-v1/modules/module-overview-template.mdx
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: 'MODULE NAME - Overview'
----
-
-`{INSERT MODULE WALKTHRU VIDEO}`
-
-
- content here
-
-
- - [`{QUESTION 1}`](`{LOOM VIDEO LINK}`)
- - Embedded link:
- - [`{QUESTION 2}`](`{LOOM VIDEO LINK}`)
- - Embedded link:
- - [`{QUESTION 3}`](`{LOOM VIDEO LINK}`)
- - Embedded link:
-
-
- content here
-
\ No newline at end of file
diff --git a/data-activation/managed-bi-v1/modules/new-customer-analysis-module.mdx b/data-activation/managed-bi-v1/modules/new-customer-analysis-module.mdx
index 0310b7b..daa21ed 100644
--- a/data-activation/managed-bi-v1/modules/new-customer-analysis-module.mdx
+++ b/data-activation/managed-bi-v1/modules/new-customer-analysis-module.mdx
@@ -1,5 +1,6 @@
---
title: "The New Customer Analysis Module"
+description: "Overview of the The New Customer Analysis Module module and how to use it."
sidebarTitle: "New Customer Analysis"
icon: 'hand'
---
@@ -21,4 +22,4 @@ icon: 'hand'
#### Potential Reporting Differences & Discrepancies
-Customers are surfaced whose first order is within the dates selected in the date range filter.
\ No newline at end of file
+Customers are surfaced whose first order is within the dates selected in the date range filter.
diff --git a/data-activation/managed-bi-v1/modules/nick-report-page-template.mdx b/data-activation/managed-bi-v1/modules/nick-report-page-template.mdx
deleted file mode 100644
index 265513f..0000000
--- a/data-activation/managed-bi-v1/modules/nick-report-page-template.mdx
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "The XXXXXXXXX Module"
-sidebarTitle: "XXXXXXXXXX Deep Dive"
-icon: 'globe'
----
-#### What is the XXXXXXXX and what data can be found there?
- Notes possibly bulleted
-
-#### Common Questions & Insights That Can Be Answered Here:
-
-
-Words or links
-
-
-
-
-
-Words or links
-
-
-
-
-
-Words or links
-
-
-
-
-
-
-#### Potential Reporting Differences & Discrepancies
-Notes possibly bulleted
diff --git a/data-activation/managed-bi-v1/modules/orders-deep-dive-module.mdx b/data-activation/managed-bi-v1/modules/orders-deep-dive-module.mdx
index b7bd2f4..b0f670a 100644
--- a/data-activation/managed-bi-v1/modules/orders-deep-dive-module.mdx
+++ b/data-activation/managed-bi-v1/modules/orders-deep-dive-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Orders Deep Dive Module"
+description: "Overview of the The Orders Deep Dive Module module and how to use it."
sidebarTitle: "Orders Deep Dive"
icon: 'dollar-sign'
---
@@ -10,17 +11,8 @@ icon: 'dollar-sign'
- Data is segmented by Channel and is defaulted to be Online DTC. Financial status is defaulted to show orders that are partially refunded and paid.
- Source/Medium reports on Last-Click Attribution within the Orders Deep Dive.
- **SourceMedium uses a waterfall of logic for attribution. Our logic is as follows:**
- ```
- 1. Shopify UTM Values
- 2. GA UTMs if it doesn't exist in Shopify
- 3. Referring domain if it isn't in GA
- 4. Dependent on being a Subscription or Non-Subscription:
- a. Subscription
- i. New sub (subscription/first_order)
- b. Non-Subscription
- i. (none)/(none)
- ```
+ SourceMedium uses the **Attribution Source Hierarchy** to select last-click UTM attribution when multiple systems capture attribution for an order.
+ See [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy) for the exact priority order and details.
#### Common Questions & Insights That Can Be Answered Here:
@@ -40,15 +32,9 @@ icon: 'dollar-sign'
#### Potential Reporting Differences & Discrepancies
-SourceMedium reports on Last-Click Attribution within the Orders Deep Dive and follows the Waterfall Logic below:
- ```
- 1. Shopify UTM Values
- 2. GA UTMs if it doesn't exist in Shopify
- 3. Referring domain if it isn't in GA
- 4. Dependent on being a Subscription or Non-Subscription:
- a. Subscription
- i. New sub (subscription/first_order)
- b. Non-Subscription
- i. (none)/(none)
- ```
\ No newline at end of file
+SourceMedium reports on Last-Click Attribution within the Orders Deep Dive using the [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy).
+
+If no UTM attribution is found, the default value depends on order type:
+- **Subscription orders**: `subscription/first_order`
+- **Non-subscription orders**: `(none)/(none)`
diff --git a/data-activation/managed-bi-v1/modules/post-purchase-survey-module.mdx b/data-activation/managed-bi-v1/modules/post-purchase-survey-module.mdx
index 5dc8842..1e337b4 100644
--- a/data-activation/managed-bi-v1/modules/post-purchase-survey-module.mdx
+++ b/data-activation/managed-bi-v1/modules/post-purchase-survey-module.mdx
@@ -1,5 +1,156 @@
---
-title: "The Post Purchase Survey Module"
-sidebarTitle: "Post Purchase Survey"
-icon: 'bullseye'
+title: "Post-Purchase Survey Module"
+sidebarTitle: "Post-Purchase Survey"
+description: "Analyze zero-party attribution data from HDYHAU surveys to understand how customers discover your brand"
+icon: "bullseye"
---
+
+The Post-Purchase Survey Module surfaces **zero-party attribution data**—self-reported responses from "How Did You Hear About Us?" (HDYHAU) surveys.
+
+
+Zero-party data complements tracking-based attribution by capturing channels that are hard to track: word of mouth, podcasts, influencers, and offline media.
+
+
+## Prerequisites
+
+To use this module, you need:
+1. A post-purchase survey tool (Fairing, KnoCommerce, or similar)
+2. Order tagging enabled (survey responses tagged to orders)
+3. Consistent tag format (e.g., `HDYHAU-Facebook`, `PPS-TikTok`)
+
+See [Post-Purchase Survey Best Practices](/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey) for setup guidance.
+
+## Key Metrics
+
+| Metric | Definition |
+|--------|------------|
+| **Response Rate** | Orders with survey response / Total orders |
+| **Channel Distribution** | % of responses attributed to each channel |
+| **Revenue by Channel** | Revenue from orders tagged with each survey response |
+| **New Customer Distribution** | Survey responses from first-time buyers only |
+
+## Module Sections
+
+### Survey Response Distribution
+
+Shows the breakdown of how customers say they discovered your brand:
+
+- **Bar chart**: Response counts by channel
+- **Pie chart**: Percentage distribution
+- **Table**: Detailed breakdown with revenue
+
+
+Compare survey attribution to your tracking-based attribution. Large gaps may indicate tracking blind spots or channels you're under-crediting.
+
+
+### Response Rate Trends
+
+Track survey completion over time:
+- Are response rates consistent?
+- Did a site change affect survey visibility?
+- Seasonal patterns in discovery channels?
+
+### Revenue Attribution
+
+Connect survey responses to business outcomes:
+- Which discovery channels drive the most revenue?
+- What's the average order value by discovery channel?
+- How does new customer LTV vary by discovery channel?
+
+## Common Analyses
+
+### 1. Tracking vs Survey Comparison
+
+Compare what tracking says vs what customers say:
+
+| Channel | Tracking Attribution | Survey Attribution | Gap |
+|---------|---------------------|-------------------|-----|
+| Meta | 45% | 25% | +20% over-credited |
+| Podcast | 0% | 12% | -12% under-credited |
+| Word of Mouth | 0% | 18% | -18% invisible to tracking |
+
+
+Gaps don't mean either source is "wrong"—they measure different things. Tracking captures last-touch interactions; surveys capture initial discovery.
+
+
+### 2. New Customer Discovery
+
+Filter to first-time buyers only to understand:
+- Where are **new** customers coming from?
+- Which channels drive **acquisition** vs re-engagement?
+
+### 3. Channel Quality Analysis
+
+Go beyond volume to measure channel quality:
+- **AOV by channel**: Do podcast customers spend more?
+- **Repeat rate by channel**: Do referral customers have higher retention?
+- **LTV by channel**: Which discovery channels drive the best long-term customers?
+
+## Interpreting Survey Data
+
+### Expected Patterns
+
+| Channel | Typical Survey % | Notes |
+|---------|------------------|-------|
+| Social (Meta, TikTok, IG) | 20-40% | Often primary for DTC brands |
+| Word of Mouth / Referral | 10-25% | Strong indicator of brand health |
+| Search (Google) | 5-15% | Usually lower than tracking shows |
+| Email | 3-8% | Rarely "first" discovery |
+| Podcast / Influencer | 5-15% | Highly variable by brand |
+| "I don't remember" | 10-20% | Expected; indicates honest responses |
+
+### Red Flags
+
+
+Watch for these data quality issues:
+
+- **Control channel > 5%**: Customers may be clicking randomly
+- **"I don't remember" < 5%**: Survey may be forcing responses
+- **Response rate < 10%**: Survey placement may need adjustment
+- **One channel > 60%**: Consider if options are too limited
+
+
+## Filtering & Segmentation
+
+Use these filters to slice survey data:
+
+| Filter | Use Case |
+|--------|----------|
+| **Date range** | Seasonal discovery patterns |
+| **Customer type** | New vs returning customer discovery |
+| **Order value** | High-value customer discovery |
+| **Product** | Product-specific discovery channels |
+| **Geography** | Regional marketing effectiveness |
+
+## Combining with Other Data
+
+### Zero-Party + First-Party Attribution
+
+For the most complete picture:
+
+1. **Survey data**: "How did you first hear about us?" (awareness)
+2. **UTM/tracking data**: Last touchpoint before purchase (conversion)
+3. **MTA data**: Multi-touch credit across the journey
+
+
+Use survey data to inform your MTA model weights. If surveys show 15% podcast discovery but tracking shows 0%, consider adding podcast as a valid touchpoint.
+
+
+See also: [Zero-party attribution](/help-center/core-concepts/attribution/zero-party-attribution) and [First-party attribution](/help-center/core-concepts/attribution/first-party-attribution).
+
+## Related Resources
+
+
+
+ How to set up effective HDYHAU surveys
+
+
+ Improve your overall attribution coverage
+
+
+ Deeper analysis of new customer behavior
+
+
+ Connect Fairing to SourceMedium
+
+
diff --git a/data-activation/managed-bi-v1/modules/product-affinity-module.mdx b/data-activation/managed-bi-v1/modules/product-affinity-module.mdx
index 0c2e555..f91c1dd 100644
--- a/data-activation/managed-bi-v1/modules/product-affinity-module.mdx
+++ b/data-activation/managed-bi-v1/modules/product-affinity-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Product Affinity Module"
+description: "Overview of the The Product Affinity Module module and how to use it."
sidebarTitle: "Product Affinity"
icon: 'bag-shopping'
---
diff --git a/data-activation/managed-bi-v1/modules/product-performance-module.mdx b/data-activation/managed-bi-v1/modules/product-performance-module.mdx
index 2c4582c..65568d8 100644
--- a/data-activation/managed-bi-v1/modules/product-performance-module.mdx
+++ b/data-activation/managed-bi-v1/modules/product-performance-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Product Performance Module"
+description: "Overview of the The Product Performance Module module and how to use it."
sidebarTitle: "Product Performance"
icon: 'bag-shopping'
---
@@ -19,4 +20,4 @@ icon: 'bag-shopping'
#### Potential Reporting Differences & Discrepancies
-This data is at the line-item level (*product, variant, SKU, etc.)*.
\ No newline at end of file
+This data is at the line-item level (*product, variant, SKU, etc.)*.
diff --git a/data-activation/managed-bi-v1/modules/repurchase-analysis-module.mdx b/data-activation/managed-bi-v1/modules/repurchase-analysis-module.mdx
index cc73c01..f20c105 100644
--- a/data-activation/managed-bi-v1/modules/repurchase-analysis-module.mdx
+++ b/data-activation/managed-bi-v1/modules/repurchase-analysis-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Repurchase Analysis Module"
+description: "Overview of the The Repurchase Analysis Module module and how to use it."
sidebarTitle: "Repurchase Analysis"
icon: 'rotate-right'
---
@@ -20,4 +21,4 @@ icon: 'rotate-right'
#### Potential Reporting Differences & Discrepancies
-This module is entirely based on a customer's order_date as opposed to when a customer is first acquired known as their `cohort_date` *(except in the case of the filters which are still applied to a customers acquisition order).*
\ No newline at end of file
+This module is entirely based on a customer's order_date as opposed to when a customer is first acquired known as their `cohort_date` *(except in the case of the filters which are still applied to a customers acquisition order).*
diff --git a/data-activation/managed-bi-v1/modules/subscription-overview-module.mdx b/data-activation/managed-bi-v1/modules/subscription-overview-module.mdx
index 7a04bdb..80fef42 100644
--- a/data-activation/managed-bi-v1/modules/subscription-overview-module.mdx
+++ b/data-activation/managed-bi-v1/modules/subscription-overview-module.mdx
@@ -1,5 +1,6 @@
---
title: "The Subscription Overview Module"
+description: "Overview of the The Subscription Overview Module module and how to use it."
sidebarTitle: "Subscription Overview"
icon: 'repeat'
---
@@ -44,4 +45,4 @@ Total `Active Subscribers`, `Churned Subscribers`, and `Active Subscriptions` ar
ReCharge does not share definitions for their dashboard's metrics with SourceMedium, thus creating a black box effect when dealing with ReCharge data. We calculate subscriber metrics in-house (aside from Subscribers Active, Subscribers Churned, and Subscriptions Active) based on the same exact ReCharge raw data used to power their built-in analytics, so we're confident in what we're reporting and its underlying logic, but there may be slight differences vs. ReCharge.
-
\ No newline at end of file
+
diff --git a/data-activation/managed-bi-v1/modules/subscription-product-performance-module.mdx b/data-activation/managed-bi-v1/modules/subscription-product-performance-module.mdx
index 6c2e61e..9edd5ca 100644
--- a/data-activation/managed-bi-v1/modules/subscription-product-performance-module.mdx
+++ b/data-activation/managed-bi-v1/modules/subscription-product-performance-module.mdx
@@ -1,9 +1,9 @@
---
title: "The Subscription Product Performance Module"
+description: "Overview of the The Subscription Product Performance Module module and how to use it."
sidebarTitle: "Subscriptions -> Product Performance"
icon: 'repeat'
---
-
#### What is the Subscriptions Product Performance module and what data can be found there?
The Subscriptions Product Performance module evaluates subscriptions at the Product, Variant, SKU and interval levels and allows for a product-level subscription analysis.
@@ -15,4 +15,4 @@ This can be found in the **Subscription Sales Performance by Product** chart.
#### Potential Reporting Differences & Discrepancies
Some perceived discrepancies may stem from subscription metrics are calculated by SourceMedium.
-Please read the 'Potential Discrepancies' section of the [Subscription Overview module page](/data-activation/managed-bi-v1/modules/subscription-overview-module) to see how ReCharge subscription metrics are calculated in SourceMedium Reports.
\ No newline at end of file
+Please read the 'Potential Discrepancies' section of the [Subscription Overview module page](/data-activation/managed-bi-v1/modules/subscription-overview-module) to see how ReCharge subscription metrics are calculated in SourceMedium Reports.
diff --git a/data-activation/managed-bi-v1/modules/traffic-deep-dive-module.mdx b/data-activation/managed-bi-v1/modules/traffic-deep-dive-module.mdx
index 835b317..7433093 100644
--- a/data-activation/managed-bi-v1/modules/traffic-deep-dive-module.mdx
+++ b/data-activation/managed-bi-v1/modules/traffic-deep-dive-module.mdx
@@ -1,5 +1,6 @@
---
title: "The GA4 Traffic Deep Dive Module"
+description: "Overview of the The GA4 Traffic Deep Dive Module module and how to use it."
sidebarTitle: "Traffic Deep Dive"
icon: 'traffic-light-stop'
---
@@ -21,4 +22,4 @@ This can be found in the **Sessions by Device** chart.
#### Potential Reporting Differences & Discrepancies
-Revenue is as reported by GA4 and will not match Shopify-reported or marketing platform-reported revenue elsewhere in the dashboard.
\ No newline at end of file
+Revenue is as reported by GA4 and will not match Shopify-reported or marketing platform-reported revenue elsewhere in the dashboard.
diff --git a/data-activation/managed-bi-v1/modules/yoy-performance-module.mdx b/data-activation/managed-bi-v1/modules/yoy-performance-module.mdx
index e947f8d..3628900 100644
--- a/data-activation/managed-bi-v1/modules/yoy-performance-module.mdx
+++ b/data-activation/managed-bi-v1/modules/yoy-performance-module.mdx
@@ -1,5 +1,6 @@
---
title: "The YoY Performance Module"
+description: "Overview of the The YoY Performance Module module and how to use it."
sidebarTitle: "YoY Performance"
icon: 'arrow-trend-up'
---
@@ -23,8 +24,8 @@ icon: 'arrow-trend-up'
The YoY module uses the Executive Summary data source, which is designed to mirror the accounting rules present in the Shopify Sales Report, and will almost always match 1:1. However, there are some instances where you won't see a 1:1 match:
1. If your brand has our 'Exclude \$0 Orders' feature enabled, you will see a revenue and orders mismatch. This feature excludes orders with a total revenue of \$0 from all Executive Summary and Retention dashboard data. If you're unsure if you have this feature enabled, reach out to our Support team in Slack or via email at [help@sourcemedium.com](mailto:help@sourcemedium.com).
- - [See here for a deeper explanation of this feature.](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature)
+ - [See here for a deeper explanation of this feature.](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
2. If your brand has any data cleaning rules in the Channel Mapping tab your Configuration Sheet *(e.g. any rules routing orders to a channel other than Online DTC)* you will see a mismatch if only Online DTC is selected in the channel dropdown (located at the top right-hand corner of your report, under the date range filter).
- **If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between the Executive Summary and Shopify Sales report.**
\ No newline at end of file
+ **If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between the Executive Summary and Shopify Sales report.**
diff --git a/data-activation/managed-bi-v1/overview.mdx b/data-activation/managed-bi-v1/overview.mdx
index 63908c0..90dfb40 100644
--- a/data-activation/managed-bi-v1/overview.mdx
+++ b/data-activation/managed-bi-v1/overview.mdx
@@ -1,6 +1,22 @@
---
-title: "Overview"
-description: ""
+title: "Managed BI v1 Overview"
+sidebarTitle: "Overview"
+description: "How SourceMedium Managed BI v1 dashboards are structured, what’s included by default, and where to find module guides"
+icon: "chart-line"
---
-blah blah
\ No newline at end of file
+Managed BI v1 is SourceMedium’s set of pre-built Looker Studio dashboards and modules designed for fast, consistent analysis on top of the SourceMedium data layer.
+
+## What’s included
+
+- Core dashboard features (filters, selectors, exports)
+- Default modules (executive summary, marketing, product performance, retention, and more)
+- Optional modules and templates depending on your plan and integrations
+
+## Start here
+
+1. Review core dashboard functionality: [Core dashboard features](/data-activation/managed-bi-v1/core-dashboard-features)
+2. Browse module guides: [Modules index](/data-activation/managed-bi-v1/modules/index)
+3. Copy and customize templates (if applicable):
+ - [Looker Studio template copy instructions](/data-activation/template-resources/looker-studio-template-copy-instructions)
+ - [Looker Studio report template directory](/data-activation/template-resources/sm-looker-report-template-directory)
diff --git a/data-activation/managed-bi-v2/modules/executive-summary.mdx b/data-activation/managed-bi-v2/modules/executive-summary.mdx
deleted file mode 100644
index 1b0f071..0000000
--- a/data-activation/managed-bi-v2/modules/executive-summary.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Executive Summary"
-description: ""
----
\ No newline at end of file
diff --git a/data-activation/managed-bi-v2/overview.mdx b/data-activation/managed-bi-v2/overview.mdx
deleted file mode 100644
index b24b55d..0000000
--- a/data-activation/managed-bi-v2/overview.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Dashboard Overview"
-description: ""
----
\ No newline at end of file
diff --git a/data-activation/managed-data-warehouse/bi-tools.mdx b/data-activation/managed-data-warehouse/bi-tools.mdx
index 1e1c05b..308759d 100644
--- a/data-activation/managed-data-warehouse/bi-tools.mdx
+++ b/data-activation/managed-data-warehouse/bi-tools.mdx
@@ -1,9 +1,8 @@
---
title: 'Connecting BI Tools'
-description: ''
-icon: ''
+description: 'Supported BI tools and templates for connecting to a SourceMedium Managed Data Warehouse.'
+icon: "chart-line"
---
-
## Overview
With the SourceMedium Managed Data Warehouse at your disposal, you unlock a range of possibilities for data analysis and visualization.
@@ -23,4 +22,4 @@ See instructions for how to leverage these templates [here](/data-activation/tem
## Other BI Tools To Consider
- [Tableau](https://www.tableau.com/)
- [Microsoft Power BI](https://www.microsoft.com/en-us/power-platform/products/power-bi)
-- [Metabase](https://www.metabase.com/)
\ No newline at end of file
+- [Metabase](https://www.metabase.com/)
diff --git a/data-activation/managed-data-warehouse/metrics-and-semantic-layer.mdx b/data-activation/managed-data-warehouse/metrics-and-semantic-layer.mdx
new file mode 100644
index 0000000..ac0d9ff
--- /dev/null
+++ b/data-activation/managed-data-warehouse/metrics-and-semantic-layer.mdx
@@ -0,0 +1,83 @@
+---
+title: "How to Use Metrics (Semantic Layer)"
+sidebarTitle: "Metrics"
+description: "How SourceMedium defines metrics once and uses them consistently across dashboards, recipes, and (when enabled) the dbt Semantic Layer."
+icon: "chart-bar"
+---
+
+SourceMedium supports multiple “levels” of querying, depending on what you’re trying to do:
+
+- **Report tables (`rpt_*`)**: fastest for common dashboard-style questions
+- **One Big Tables (`obt_*`)**: flexible analysis with pre-modeled joins and business logic
+- **Semantic metrics**: a single “metric definition layer” so the *same* metrics power dashboards and saved queries
+
+This page focuses on the **semantic metric layer** and how it connects to:
+- Managed BI dashboard tiles
+- The [SQL Query Library](/data-activation/template-resources/sql-query-library)
+
+## Metric definitions (single source of truth)
+
+Metric definitions are documented in:
+- [Metric Definitions](/onboarding/data-docs/metrics)
+
+In the dbt project, semantic layer definitions live under `models/semantic/` (semantic models + metrics + saved queries).
+
+## When to use semantic metrics vs raw tables
+
+Use semantic metrics when you need:
+- Consistent metric logic across tools (dashboards, ad-hoc analysis, exports)
+- Standardized naming (no “two versions” of CAC/ROAS/net revenue)
+- The ability to group metrics by dimensions without re-writing business logic
+
+Use raw tables (OBT/RPT) when you need:
+- Custom fields not covered by metrics
+- Deep row-level inspection and debugging
+
+## Saved queries (recommended starting points)
+
+The semantic layer includes a set of **saved queries** designed to match common “dashboard tile” questions.
+If you’re using the Query Library, these saved queries also map cleanly to sections/recipes.
+
+| Saved query | Best for | Commonly maps to | Query Library section |
+|------------|----------|------------------|-----------------------|
+| `executive_metrics_daily` | Core order KPIs by day | Executive Summary | Orders & Revenue |
+| `simple_executive_metrics_daily` | Fast channel comparisons (pre-aggregated) | Executive Summary / Marketing Overview | Marketing & Ads / Orders & Revenue |
+| `marketing_performance_daily` | Ad spend + platform-reported performance | Marketing Overview / platform modules | Marketing & Ads |
+| `revenue_breakdown_daily` | Full daily revenue breakdown (incl. discounts/refunds) | Executive Summary | Orders & Revenue |
+| `revenue_cumulative_daily` | MTD/QTD/YTD + trailing periods | Executive Summary | Orders & Revenue |
+| `customer_metrics_daily` | New vs repeat behavior and revenue | LTV & Retention / New Customer Analysis | Customers & Retention / LTV & Retention |
+| `product_performance_daily` | Product catalog & mix monitoring | Product Performance | Products |
+| `simple_conversion_metrics_daily` | High-level conversion rates by channel | Traffic Deep Dive / Executive | Funnel |
+| `channel_conversion_metrics_daily` | Conversion + MER by channel | Marketing Overview / Executive | Funnel / Marketing & Ads |
+| `detailed_conversion_metrics_daily` | UTM-level conversion analysis | Traffic Deep Dive | Funnel |
+| `conversion_metrics_detailed_daily` | Landing page + UTM conversion deep dive | Traffic Deep Dive | Funnel |
+
+
+“Dashboard tile” mappings above are intended as practical starting points, not hard guarantees. Not every brand has every integration, and coverage can vary by source system.
+
+
+## How this relates to the SQL Query Library
+
+If you prefer writing SQL directly in BigQuery, the Query Library recipes are pre-built around the same core concepts:
+- Valid order filtering (`is_order_sm_valid = TRUE`)
+- Stable “analysis tables” (`obt_*` and `rpt_*`)
+- Lowercased categorical groupings for safe aggregation
+
+Start here:
+- [SQL Query Library](/data-activation/template-resources/sql-query-library)
+- [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- [`rpt_executive_summary_daily`](/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily)
+
+## (Optional) Querying via dbt Semantic Layer
+
+If you have dbt Semantic Layer tooling enabled (e.g., MetricFlow), you can query metrics using a CLI interface instead of writing SQL.
+
+```bash
+# Example (dbt CLI / Semantic Layer):
+dbt sl query order_net_revenue --group-by "TimeDimension('metric_time', 'day')" --limit 30
+```
+
+
+If you don’t have Semantic Layer tooling enabled, use the SQL Query Library + OBT/RPT tables instead.
+
+
diff --git a/data-activation/managed-data-warehouse/modeling.mdx b/data-activation/managed-data-warehouse/modeling.mdx
index 549226a..130e8ad 100644
--- a/data-activation/managed-data-warehouse/modeling.mdx
+++ b/data-activation/managed-data-warehouse/modeling.mdx
@@ -1,6 +1,180 @@
---
-title: "Modeling With SourceMedium"
-description: ""
+title: "Modeling with SourceMedium"
+description: "How to build custom models on top of SourceMedium tables: best practices, common patterns, and example queries"
+icon: "cubes"
---
-(Coming soon...)
\ No newline at end of file
+This guide covers how to extend SourceMedium's data models by building your own tables, views, or queries in your Managed Data Warehouse.
+
+## Before you start
+
+Understand [our table types](/data-transformations/philosophy#how-we-shape-our-data):
+- **`obt_*`** (One Big Tables) — Best starting point for most analyses. Pre-joined, business-ready.
+- **`fct_*`** / **`dim_*`** — Granular building blocks for custom joins.
+- **`rpt_*`** — Pre-aggregated for specific reporting use cases.
+
+
+Start with `obt_` tables when possible. They're designed as a semantic layer and handle most common joins for you.
+
+
+## Recommended approach
+
+### 1. Start with OBT tables
+
+For most custom analyses, `obt_orders` and `obt_customers` provide everything you need:
+
+```sql
+-- Example: Custom cohort analysis
+WITH first_valid_order AS (
+ SELECT
+ sm_customer_key,
+ MIN(order_processed_at) AS first_valid_order_processed_at
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ GROUP BY 1
+)
+SELECT
+ DATE_TRUNC(DATE(first_valid_order_processed_at), MONTH) AS cohort_month,
+ COUNT(DISTINCT o.sm_customer_key) AS customers,
+ SUM(o.order_net_revenue) AS total_revenue
+FROM `your_project.sm_transformed_v2.obt_orders` o
+JOIN first_valid_order f
+ ON o.sm_customer_key = f.sm_customer_key
+WHERE o.is_order_sm_valid = TRUE
+GROUP BY 1
+ORDER BY 1
+```
+
+### 2. Join fact + dimension tables for granular needs
+
+When OBTs don't have the grain you need:
+
+```sql
+-- Example: Order line-level analysis with product details
+SELECT
+ order_id,
+ product_title,
+ order_line_net_revenue,
+ product_type
+FROM `your_project.sm_transformed_v2.obt_order_lines`
+WHERE is_order_sm_valid = TRUE
+```
+
+### 3. Use report tables for pre-aggregated metrics
+
+Don't re-aggregate what's already computed:
+
+```sql
+-- Example: Daily ad performance already aggregated
+SELECT
+ date,
+ sm_channel,
+ ad_spend,
+ ad_platform_reported_revenue,
+ SAFE_DIVIDE(ad_platform_reported_revenue, ad_spend) AS roas
+FROM `your_project.sm_transformed_v2.rpt_ad_performance_daily`
+WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+```
+
+## Common join keys
+
+| Table Type | Primary Key | Common Join Keys |
+|-----------|-------------|------------------|
+| Orders | `sm_order_key` | `sm_customer_key`, `sm_store_id`, `source_system` |
+| Order Lines | `sm_order_line_key` | `sm_order_key`, `sm_product_variant_key` |
+| Customers | `sm_customer_key` | `sm_store_id`, `source_system` |
+| Products | `sm_product_variant_key` | `product_id`, `variant_id` |
+
+
+Always filter by `sm_store_id` (SourceMedium store identifier) when working across brands or stores to avoid cross-contamination.
+
+
+## Best practices
+
+### Filter to valid orders
+Always include `is_order_sm_valid = TRUE` to exclude test orders, cancelled orders, and other invalid transactions:
+
+```sql
+SELECT COUNT(*) AS valid_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE;
+```
+
+### Use consistent revenue definitions
+Pick one and stick with it across your models:
+- `order_net_revenue` — After discounts, refunds, taxes
+- `order_gross_revenue` — Before adjustments
+
+### Partition and cluster your models
+If creating persistent tables, optimize for query performance:
+
+```text
+CREATE TABLE `your_project.your_dataset.custom_model`
+PARTITION BY DATE(order_created_at)
+CLUSTER BY sm_store_id, sm_channel
+AS (
+ SELECT ...
+)
+```
+
+### Document your models
+Add descriptions so others (and future you) understand the logic:
+
+```sql
+-- Model: custom_weekly_cohort_summary
+-- Purpose: Weekly cohort LTV for finance reporting
+-- Owner: analytics@yourcompany.com
+-- Last updated: 2026-01-15
+SELECT 1 AS ok;
+```
+
+## Common patterns
+
+### Customer-level aggregations
+```sql
+SELECT
+ sm_customer_key,
+ MIN(order_created_at) AS first_order_date,
+ MAX(order_created_at) AS last_order_date,
+ COUNT(DISTINCT sm_order_key) AS order_count,
+ SUM(order_net_revenue) AS lifetime_revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+GROUP BY 1
+```
+
+### Channel attribution analysis
+```sql
+SELECT
+ sm_channel,
+ sm_sub_channel,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND DATE(order_created_at) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+GROUP BY 1, 2
+ORDER BY revenue DESC
+```
+
+### Product affinity (what's bought together)
+```sql
+SELECT
+ a.product_title AS product_a,
+ b.product_title AS product_b,
+ COUNT(DISTINCT a.sm_order_key) AS co_purchase_count
+FROM `your_project.sm_transformed_v2.obt_order_lines` a
+JOIN `your_project.sm_transformed_v2.obt_order_lines` b
+ ON a.sm_order_key = b.sm_order_key
+ AND a.sm_order_line_key < b.sm_order_line_key
+WHERE a.is_order_sm_valid = TRUE
+GROUP BY 1, 2
+HAVING co_purchase_count >= 10
+ORDER BY co_purchase_count DESC
+```
+
+## Next steps
+
+- Browse available tables: [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2)
+- Connect your BI tool: [BI Tools Setup](/data-activation/managed-data-warehouse/bi-tools)
+- Learn naming conventions: [Column Naming Standards](/data-transformations/naming-conventions/key-concepts)
diff --git a/data-activation/managed-data-warehouse/overview.mdx b/data-activation/managed-data-warehouse/overview.mdx
index 611bd50..42cf619 100644
--- a/data-activation/managed-data-warehouse/overview.mdx
+++ b/data-activation/managed-data-warehouse/overview.mdx
@@ -1,12 +1,12 @@
---
-title: 'Overview'
-description: ''
-icon: ''
+title: "Managed Data Warehouse (MDW) Overview"
+sidebarTitle: "Overview"
+description: "What SourceMedium’s Managed Data Warehouse is and how to activate it via BI templates or custom modeling."
+icon: "chart-line"
---
-
## What Is A Managed Data Warehouse?
-SourceMedium's Managed Data Warehouse offering helps simplify data warehouse adoption, a tablestakes
+SourceMedium's Managed Data Warehouse offering helps simplify data warehouse adoption, a table-stakes
technology investment for businesses looking to establish a competitive advantage through data and advanced analytics.
Once we've ingested data from the sources you've integrated, we run our [transformation pipeline](/data-transformations/philosophy) and deliver data into a
diff --git a/data-activation/template-resources/copying-sm-data-source-templates.mdx b/data-activation/template-resources/copying-sm-data-source-templates.mdx
index 44e3c44..e5207c5 100644
--- a/data-activation/template-resources/copying-sm-data-source-templates.mdx
+++ b/data-activation/template-resources/copying-sm-data-source-templates.mdx
@@ -1,5 +1,26 @@
---
title: "Copying SourceMedium Data Source Templates"
-description: ""
+description: "How to copy SourceMedium Looker Studio data source templates and map them to your warehouse tables"
+icon: "book"
---
-blah blah
\ No newline at end of file
+
+Use this guide to copy SourceMedium-provided Looker Studio **data source templates** and connect them to your environment.
+
+## When to use this
+
+- You want to build new reports using the SourceMedium table layer without recreating fields from scratch.
+- You want to start from an existing template and modify dimensions/metrics.
+
+## Prerequisites
+
+- Access to Looker Studio
+- Access to your SourceMedium datasets in BigQuery (or your managed warehouse, if applicable)
+
+## Steps
+
+1. Start with the template directory (if provided by your team).
+2. Make a copy of the data source.
+3. Map the copied data source to your account’s tables/datasets.
+4. Validate field types (dates, numbers, booleans) before building charts.
+
+If you’re copying full reports (dashboards), start with: [Copying SourceMedium report templates](/data-activation/template-resources/copying-sm-report-templates)
diff --git a/data-activation/template-resources/copying-sm-report-templates.mdx b/data-activation/template-resources/copying-sm-report-templates.mdx
index 32c1624..ebb85ed 100644
--- a/data-activation/template-resources/copying-sm-report-templates.mdx
+++ b/data-activation/template-resources/copying-sm-report-templates.mdx
@@ -1,5 +1,16 @@
---
title: "Copying SourceMedium Report Templates"
-description: ""
+description: "How to copy a SourceMedium Looker Studio report template and map data sources to your environment"
+icon: "book"
---
-blah blah
\ No newline at end of file
+
+Use this guide to copy a SourceMedium Looker Studio **report template** (dashboard) and connect it to your data.
+
+## Start here
+
+- [Looker Studio template copy instructions](/data-activation/template-resources/looker-studio-template-copy-instructions)
+
+## Tips
+
+- Keep your copied report name distinct (include your brand and date).
+- Validate the underlying data sources first (dates + key metrics) before styling or rearranging pages.
diff --git a/data-activation/template-resources/looker-studio-template-copy-instructions.mdx b/data-activation/template-resources/looker-studio-template-copy-instructions.mdx
index 1b7dce6..e3b36c5 100644
--- a/data-activation/template-resources/looker-studio-template-copy-instructions.mdx
+++ b/data-activation/template-resources/looker-studio-template-copy-instructions.mdx
@@ -2,7 +2,7 @@
title: 'Looker Studio - Base Template Copy Instructions'
sidebarTitle: 'Template Instructions'
description: "How to use SourceMedium's Looker Studio templates"
-icon: ''
+icon: "book"
---
Below, we outline how you can easily leverage our Looker Studio report templates for our `obt_orders`
@@ -34,4 +34,4 @@ BI template uses.
- You can find more information on setting up Google Groups and our best practices [here](https://support.google.com/groups/answer/46601?hl=en)

-
\ No newline at end of file
+
diff --git a/data-activation/template-resources/sm-looker-data-source-template-directory.mdx b/data-activation/template-resources/sm-looker-data-source-template-directory.mdx
index 44fd92c..850164f 100644
--- a/data-activation/template-resources/sm-looker-data-source-template-directory.mdx
+++ b/data-activation/template-resources/sm-looker-data-source-template-directory.mdx
@@ -1,8 +1,8 @@
---
title: 'Looker Studio - Data Source Template Directory'
sidebarTitle: 'Data Source Template Directory'
-description: ''
-icon: ''
+description: 'Directory of Looker Studio data source templates mapped to SourceMedium tables'
+icon: 'database'
---
## Overview
@@ -15,11 +15,11 @@ Start building your own Looker Studio reports using SourceMedium's out of the bo
| Data Source | Table Name(s) | Description | Present on (templates) |
|-----------------------------|----------------|------------------------|------------------------------------------------------------|
-| [[DEMO] Executive Summary](https://lookerstudio.google.com/datasources/4a3fee17-43a6-4058-b58c-235467b61da8) | `sm_transformed_v2.rpt_executive_summary_daily` | Contains daily aggregated metrics across all of the data sources integrated with SourceMedium | SourceMedium v2 Template
|
-| [[Demo] Orders](https://lookerstudio.google.com/datasources/167f7529-5246-4aa4-a34c-e9045955b035) | `sm_transformed_v2.obt_orders` | Contains fully joined order facts and order dimensions | SourceMedium v2 Template
|
-| [[DEMO] Order lines](https://lookerstudio.google.com/datasources/5a50a9c3-18e3-4a78-bcf0-d259dafdb1da) | `sm_transformed_v2.obt_order_lines` | Contains fully joined order line facts and order line dimensions | SourceMedium v2 Template
|
-| [[DEMO] Customers With First & Last Orders](https://lookerstudio.google.com/datasources/353645ee-0007-4002-9791-387a2883da59) | `sm_views.rpt_customers_first_last` | Contains customer metadata joined to acquisition & latest order performance | SourceMedium v2 Template
[Customer Data Explorer](https://lookerstudio.google.com/s/uVqXw4cs9ic)
|
-| [[DEMO] Data Quality Test Results](https://lookerstudio.google.com/datasources/79fddaf7-a325-4669-aeed-5ef0eba6585c) | `sm_metadata.rpt_data_quality_test_results` | Test results for the various data quality checks performed on your data | SourceMedium v2 Template
|
\ No newline at end of file
+| [\[DEMO\] Executive Summary](https://lookerstudio.google.com/datasources/4a3fee17-43a6-4058-b58c-235467b61da8) | `sm_transformed_v2.rpt_executive_summary_daily` | Contains daily aggregated metrics across all of the data sources integrated with SourceMedium | SourceMedium v2 Template
|
+| [\[Demo\] Orders](https://lookerstudio.google.com/datasources/167f7529-5246-4aa4-a34c-e9045955b035) | `sm_transformed_v2.obt_orders` | Contains fully joined order facts and order dimensions | SourceMedium v2 Template
|
+| [\[DEMO\] Order lines](https://lookerstudio.google.com/datasources/5a50a9c3-18e3-4a78-bcf0-d259dafdb1da) | `sm_transformed_v2.obt_order_lines` | Contains fully joined order line facts and order line dimensions | SourceMedium v2 Template
|
+| [\[DEMO\] Customers With First & Last Orders](https://lookerstudio.google.com/datasources/353645ee-0007-4002-9791-387a2883da59) | `sm_views.rpt_customers_first_last` | Contains customer metadata joined to acquisition & latest order performance | SourceMedium v2 Template
[Customer Data Explorer](https://lookerstudio.google.com/s/uVqXw4cs9ic)
|
+| [\[DEMO\] Data Quality Test Results](https://lookerstudio.google.com/datasources/79fddaf7-a325-4669-aeed-5ef0eba6585c) | `sm_metadata.rpt_data_quality_test_results` | Test results for the various data quality checks performed on your data | SourceMedium v2 Template
|
diff --git a/data-activation/template-resources/sm-looker-report-template-directory.mdx b/data-activation/template-resources/sm-looker-report-template-directory.mdx
index 6a4f479..3325d75 100644
--- a/data-activation/template-resources/sm-looker-report-template-directory.mdx
+++ b/data-activation/template-resources/sm-looker-report-template-directory.mdx
@@ -1,10 +1,9 @@
---
title: 'Looker Studio - Report Template Directory'
sidebarTitle: 'Report Template Directory'
-description: ''
-icon: ''
+description: 'Directory of SourceMedium Looker Studio report templates and the data sources required for each.'
+icon: "book"
---
-
## Overview
Level up your BI with one of SourceMedium's pre-compiled report templates. Create your own template copy and use as-is, or as a starting point for your own customized views!
@@ -15,7 +14,7 @@ Level up your BI with one of SourceMedium's pre-compiled report templates. Crea
| Report | Description | Required Data Sources |
|--------|-------------|-----------------------|
-| [SourceMedium v2 Template](https://lookerstudio.google.com/reporting/655de73a-1df6-432e-b62b-3a99b9779f1a/page/p_61whutv4ed) | SourceMedium's latest base template. Provides out of the box value for C-suites and analysts alike, with plenty of room to build on top. |
[[DEMO] Order lines OBT](https://lookerstudio.google.com/datasources/7dba72df-2c0b-46c1-9d45-731e4c557625)
[[DEMO] Customers First / Last RPT](https://lookerstudio.google.com/datasources/353645ee-0007-4002-9791-387a2883da59)
|
+| [SourceMedium v2 Template](https://lookerstudio.google.com/reporting/655de73a-1df6-432e-b62b-3a99b9779f1a/page/p_61whutv4ed) | SourceMedium's latest base template. Provides out of the box value for C-suites and analysts alike, with plenty of room to build on top. |
[\[DEMO\] Order lines OBT](https://lookerstudio.google.com/datasources/7dba72df-2c0b-46c1-9d45-731e4c557625)
[\[DEMO\] Customers First / Last RPT](https://lookerstudio.google.com/datasources/353645ee-0007-4002-9791-387a2883da59)
|
{/*
| []() | |
|
*/}
diff --git a/data-activation/template-resources/sm-sql-recipe-directory.mdx b/data-activation/template-resources/sm-sql-recipe-directory.mdx
deleted file mode 100644
index 67b812b..0000000
--- a/data-activation/template-resources/sm-sql-recipe-directory.mdx
+++ /dev/null
@@ -1,133 +0,0 @@
----
-title: 'SQL Recipe Directory'
-description: ''
-icon: ''
----
-
-### Overview
-
-blah blah
-
-## Product Insights
-
-
- ```SQL
- WITH RECURSIVE `CTE` AS (
- -- Anchor Query
- SELECT
- p.smcid,
- p.order_id,
- 1 AS length,
- concat(p.product_title, ' - ', p.variant_title) AS combo,
- concat(p.product_title, ' - ', p.variant_title) AS lastitem
- FROM `customers-managed.masterset.product_performance` AS p
- WHERE p.smcid = 'lilacst'
-
- UNION ALL
- -- Recursive Part
- SELECT
- p.smcid,
- p.order_id,
- r.length + 1 AS length,
- CONCAT(r.combo, ', ', concat(p.product_title, ' - ', p.variant_title)) AS combo,
- concat(p.product_title, ' - ', p.variant_title) AS lastitem
- FROM `CTE` AS r
- INNER JOIN `customers-managed.masterset.product_performance` AS p
- ON
- p.order_id = r.order_id
- AND concat(p.product_title, ' - ', p.variant_title) > r.lastitem
- WHERE r.length < 5
- )
-
- -- Output query
- SELECT
- combo as combinations,
- COUNT(DISTINCT order_id) AS frequency,
- (CHAR_LENGTH(combo) - CHAR_LENGTH(REPLACE(combo, ',', '')))+1 as number_of_products
- FROM `CTE`
- WHERE (CHAR_LENGTH(combo) - CHAR_LENGTH(REPLACE(combo, ',', ''))) >= 2
- GROUP BY combo
- HAVING frequency >= 1000
- ORDER BY frequency DESC, combo ASC;
- ```
-
-
-
-
-## Subscription Insights
-
-
-
- ```SQL
-
- ```
-
-
- ```SQL
-
- ```
-
-
- ```SQL
-
- ```
-
-
-
-
-## Marketing Insights
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
-
-## Repurchase Analysis
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
- ```SQL
-
- ```
-
-
-
-
diff --git a/data-activation/template-resources/sql-query-library.mdx b/data-activation/template-resources/sql-query-library.mdx
new file mode 100644
index 0000000..567af8e
--- /dev/null
+++ b/data-activation/template-resources/sql-query-library.mdx
@@ -0,0 +1,3009 @@
+---
+title: 'SQL Query Library'
+sidebarTitle: "SQL Query Library"
+description: "Copy/paste BigQuery SQL templates to answer common questions using SourceMedium tables"
+icon: "code"
+---
+
+## Overview
+
+Use these queries as starting points for analysis in BigQuery. Replace `your_project` with your BigQuery project ID (e.g., `sm-yourcompany`) and `your-sm_store_id` with your store identifier.
+
+
+**Query Standards:**
+- Always include `is_order_sm_valid = TRUE` for order-based analyses
+- If you have multiple stores, add `sm_store_id = 'your-sm_store_id'` to filter for a specific store's data
+- Use `your_project.sm_transformed_v2.*` for standard tables
+- Use `your_project.sm_experimental.*` for MTA tables
+
+
+If you're not sure which table to use, start with: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders) and [`obt_order_lines`](/data-activation/data-tables/sm_transformed_v2/obt_order_lines).
+
+---
+
+## Quick Links
+
+| Section | What's inside |
+|---------|---------------|
+| [Marketing & Ads](#marketing--ads) | CAC, ROAS by platform, ROAS trends |
+| [Messaging](#messaging) | Email/SMS performance, flows vs campaigns, list growth |
+| [Funnel](#funnel) | Funnel step counts, conversion rates, top converting pages |
+| [Journeys & Lead Capture](#journeys--lead-capture) | Lead capture → purchase timing, landing pages, first vs last touch (MTA) |
+| [Customers & Retention](#customers--retention) | First vs repeat orders, repeat rates by source, new vs repeat trends |
+| [Products](#products) | Top products by revenue/units, gateway products, product combos |
+| [Orders & Revenue](#orders--revenue) | AOV by channel, subscription revenue, refund rates, sales channel mix |
+| [LTV & Retention](#ltv--retention) | Cohort LTV, payback period, LTV:CAC, repeat purchase rates, 90-day LTV by product |
+| [Attribution & Data Health](#attribution--data-health) | Table freshness, UTM coverage, fallback signals, click-id coverage, tracking regressions |
+| [Customer Support](#customer-support) | Ticket volume, one-touch rate, resolution time, CSAT |
+
+---
+
+
+Most examples default to the last 30 days for performance and "current state" analysis. Adjust the timeframe and add `sm_store_id` scoping when needed.
+
+
+## Marketing & Ads
+
+
+
+ **What you'll learn:** How much you're spending to acquire each new customer, broken down by channel. Use this to identify which channels are most cost-efficient and where you might be overspending on acquisition.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=CAC=ad_spend/new_customer_count | grain=sm_channel | scope=all_channels
+ WITH channel_rollup AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_channel)), ''), '(unknown)') AS sm_channel,
+ SUM(ABS(ad_spend)) AS ad_spend,
+ SUM(new_customer_count) AS new_customers
+ FROM `your_project.sm_transformed_v2.rpt_executive_summary_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND ad_spend IS NOT NULL
+ AND new_customer_count IS NOT NULL
+ GROUP BY 1
+ ),
+ overall AS (
+ SELECT
+ '(all_channels)' AS sm_channel,
+ SUM(ABS(ad_spend)) AS ad_spend,
+ SUM(new_customer_count) AS new_customers
+ FROM `your_project.sm_transformed_v2.rpt_executive_summary_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND ad_spend IS NOT NULL
+ AND new_customer_count IS NOT NULL
+ )
+ SELECT
+ sm_channel,
+ ad_spend,
+ new_customers,
+ SAFE_DIVIDE(ad_spend, NULLIF(new_customers, 0)) AS cac
+ FROM channel_rollup
+ WHERE ad_spend > 0
+
+ UNION ALL
+
+ SELECT
+ sm_channel,
+ ad_spend,
+ new_customers,
+ SAFE_DIVIDE(ad_spend, NULLIF(new_customers, 0)) AS cac
+ FROM overall
+ WHERE ad_spend > 0
+ ORDER BY cac ASC;
+ ```
+
+
+
+ **What you'll learn:** Which ad platform and campaign type combinations are generating the best return on ad spend. Helps you decide where to allocate more budget and which underperforming campaigns to optimize or cut.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=ROAS=platform_reported_revenue/ad_spend | grain=platform+campaign_type | scope=all_stores
+ SELECT
+ sm_store_id,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS platform,
+ COALESCE(NULLIF(LOWER(TRIM(ad_campaign_type)), ''), '(unknown)') AS campaign_type,
+ SUM(ad_platform_reported_revenue) AS platform_reported_revenue,
+ SUM(ad_spend) AS ad_spend,
+ SAFE_DIVIDE(SUM(ad_platform_reported_revenue), NULLIF(SUM(ad_spend), 0)) AS roas
+ FROM `your_project.sm_transformed_v2.rpt_ad_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND ad_spend > 0
+ GROUP BY 1, 2, 3
+ ORDER BY roas DESC
+ LIMIT 20;
+ ```
+
+
+
+ **What you'll learn:** How your ad efficiency has changed month-over-month by platform. Spot seasonal patterns, detect declining performance early, or confirm that recent optimizations are working.
+
+ ```sql
+ -- Assumptions: timeframe=last_6_months | metric=ROAS=platform_reported_revenue/ad_spend | grain=month+platform | scope=all_stores
+ WITH monthly AS (
+ SELECT
+ DATE_TRUNC(date, MONTH) AS month_start,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS platform,
+ SUM(ad_platform_reported_revenue) AS platform_reported_revenue,
+ SUM(ad_spend) AS ad_spend
+ FROM `your_project.sm_transformed_v2.rpt_ad_performance_daily`
+ WHERE date >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 6 MONTH)
+ AND date < DATE_ADD(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 1 MONTH)
+ AND ad_spend > 0
+ GROUP BY 1, 2
+ )
+ SELECT
+ platform,
+ month_start,
+ ad_spend,
+ platform_reported_revenue,
+ SAFE_DIVIDE(platform_reported_revenue, NULLIF(ad_spend, 0)) AS roas
+ FROM monthly
+ ORDER BY platform, month_start;
+ ```
+
+
+
+## Messaging
+
+
+
+ **What you'll learn:** How email/SMS/push performance differs between **campaigns** and **flows**, including deliverability, engagement, list growth, and platform-attributed orders/revenue. Use this to quickly identify which message types are driving the most value (and where engagement or unsubscribes are trending poorly).
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=engagement+platform_attributed_orders_revenue | grain=channel+message_type | scope=all_messages
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ COALESCE(NULLIF(LOWER(TRIM(message_type)), ''), '(unknown)') AS message_type,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_opens) AS opens,
+ SUM(message_unique_clicks) AS clicks,
+ SUM(message_unique_bounces) AS bounces,
+ SUM(message_unique_drops) AS drops,
+ SUM(list_subscribes) AS list_subscribes,
+ SUM(list_unsubscribes) AS list_unsubscribes,
+ SUM(platform_reported_orders) AS platform_reported_orders,
+ SUM(platform_reported_order_revenue) AS platform_reported_order_revenue,
+ SAFE_DIVIDE(SUM(message_unique_opens), NULLIF(SUM(message_unique_receives), 0)) AS open_rate,
+ SAFE_DIVIDE(SUM(message_unique_clicks), NULLIF(SUM(message_unique_receives), 0)) AS click_rate,
+ SAFE_DIVIDE(SUM(list_unsubscribes), NULLIF(SUM(message_unique_receives), 0)) AS unsubscribe_rate_per_receive
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1, 2
+ ORDER BY platform_reported_order_revenue DESC;
+ ```
+
+
+ `platform_reported_*` metrics are **platform-attributed**, not incremental lift. Use them for directional comparisons and monitoring, not causal claims.
+
+
+
+
+ **What you'll learn:** Which **campaigns** are driving the most platform-attributed revenue and orders in the last 30 days. Use this to spot your best-performing sends and quickly triage underperformers.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=platform_attributed_orders_revenue | grain=campaign | scope=campaigns_only
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ campaign_id,
+ ANY_VALUE(campaign_name) AS campaign_name,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_opens) AS opens,
+ SUM(message_unique_clicks) AS clicks,
+ SUM(platform_reported_orders) AS platform_reported_orders,
+ SUM(platform_reported_order_revenue) AS platform_reported_order_revenue,
+ SAFE_DIVIDE(SUM(message_unique_opens), NULLIF(SUM(message_unique_receives), 0)) AS open_rate,
+ SAFE_DIVIDE(SUM(message_unique_clicks), NULLIF(SUM(message_unique_receives), 0)) AS click_rate
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND LOWER(message_type) = 'campaign'
+ GROUP BY 1, 2, 3
+ ORDER BY platform_reported_order_revenue DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How list growth is trending week-over-week by channel using message-attributed subscribes and unsubscribes. Use this to detect periods of churn (high unsubscribes) and measure whether list acquisition is keeping up.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_weeks | metric=list_subscribes_unsubscribes_net | grain=week+channel | scope=all_messages
+ SELECT
+ DATE_TRUNC(date, WEEK(MONDAY)) AS week_start,
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ SUM(list_subscribes) AS list_subscribes,
+ SUM(list_unsubscribes) AS list_unsubscribes,
+ SUM(list_subscribes) - SUM(list_unsubscribes) AS net_list_growth,
+ SAFE_DIVIDE(SUM(list_unsubscribes), NULLIF(SUM(list_subscribes), 0)) AS unsubscribe_per_subscribe
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 84 DAY)
+ GROUP BY 1, 2
+ ORDER BY week_start, sm_message_channel;
+ ```
+
+
+
+ **What you'll learn:** Which messaging providers (Klaviyo, Postscript, Attentive, etc.) are driving the best engagement and platform-attributed outcomes, broken out by channel and message type. Useful when you run multiple providers or want to audit performance differences across tools.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=engagement+platform_attributed_orders_revenue | grain=provider+channel+message_type | scope=message_sends_only
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ COALESCE(NULLIF(LOWER(TRIM(message_type)), ''), '(unknown)') AS message_type,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_opens) AS opens,
+ SUM(message_unique_clicks) AS clicks,
+ SUM(platform_reported_orders) AS platform_reported_orders,
+ SUM(platform_reported_order_revenue) AS platform_reported_order_revenue,
+ SAFE_DIVIDE(SUM(message_unique_opens), NULLIF(SUM(message_unique_receives), 0)) AS open_rate,
+ SAFE_DIVIDE(SUM(message_unique_clicks), NULLIF(SUM(message_unique_receives), 0)) AS click_rate
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND message_type IS NOT NULL
+ GROUP BY 1, 2, 3
+ ORDER BY platform_reported_order_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Whether your weekly performance is being driven by flows or campaigns, including engagement and unsubscribes per receive. Helpful for diagnosing list fatigue or “campaign heavy” weeks that spike churn.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_weeks | metric=engagement+platform_attributed_revenue+unsubscribe_rate | grain=week+message_type | scope=flow_vs_campaign_only
+ SELECT
+ DATE_TRUNC(date, WEEK(MONDAY)) AS week_start,
+ LOWER(message_type) AS message_type,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_opens) AS opens,
+ SUM(message_unique_clicks) AS clicks,
+ SUM(list_unsubscribes) AS list_unsubscribes,
+ SUM(platform_reported_order_revenue) AS platform_reported_order_revenue,
+ SAFE_DIVIDE(SUM(message_unique_opens), NULLIF(SUM(message_unique_receives), 0)) AS open_rate,
+ SAFE_DIVIDE(SUM(message_unique_clicks), NULLIF(SUM(message_unique_receives), 0)) AS click_rate,
+ SAFE_DIVIDE(SUM(list_unsubscribes), NULLIF(SUM(message_unique_receives), 0)) AS unsubscribe_rate_per_receive
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 84 DAY)
+ AND LOWER(message_type) IN ('flow', 'campaign')
+ GROUP BY 1, 2
+ ORDER BY week_start, message_type;
+ ```
+
+
+ This is a directional trend view. If your providers attribute list subscribes/unsubscribes separately from message sends, keep using the dedicated “List subscribes vs unsubscribes” template for net list growth.
+
+
+
+
+ **What you'll learn:** Whether bounces or suppressed sends (“drops”) are trending up for a specific provider/channel/message type. Useful for deliverability monitoring and troubleshooting.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_weeks | metric=bounce_rate+drop_rate | grain=week+provider+channel+message_type | scope=message_sends_only
+ SELECT
+ DATE_TRUNC(date, WEEK(MONDAY)) AS week_start,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ COALESCE(NULLIF(LOWER(TRIM(message_type)), ''), '(unknown)') AS message_type,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_bounces) AS bounces,
+ SUM(message_unique_drops) AS drops,
+ SAFE_DIVIDE(SUM(message_unique_bounces), NULLIF(SUM(message_unique_receives), 0)) AS bounce_rate_per_receive,
+ SAFE_DIVIDE(SUM(message_unique_drops), NULLIF(SUM(message_unique_receives), 0)) AS drop_rate_per_receive
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 84 DAY)
+ AND message_type IS NOT NULL
+ GROUP BY 1, 2, 3, 4
+ HAVING receives >= 1000
+ ORDER BY week_start, source_system, sm_message_channel, message_type;
+ ```
+
+
+
+ **What you'll learn:** Which messages have unusually high click rates, after applying a minimum receives threshold to avoid small-sample noise. Useful for creative analysis and identifying “winner” templates to reuse.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=click_rate+platform_attributed_outcomes | grain=message | scope=min_receives_threshold
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ COALESCE(NULLIF(LOWER(TRIM(sm_message_channel)), ''), '(unknown)') AS sm_message_channel,
+ COALESCE(NULLIF(LOWER(TRIM(message_type)), ''), '(unknown)') AS message_type,
+ message_id,
+ ANY_VALUE(message_name) AS message_name,
+ ANY_VALUE(message_subject) AS message_subject,
+ campaign_id,
+ ANY_VALUE(campaign_name) AS campaign_name,
+ SUM(message_unique_receives) AS receives,
+ SUM(message_unique_opens) AS opens,
+ SUM(message_unique_clicks) AS clicks,
+ SUM(platform_reported_orders) AS platform_reported_orders,
+ SUM(platform_reported_order_revenue) AS platform_reported_order_revenue,
+ SAFE_DIVIDE(SUM(message_unique_clicks), NULLIF(SUM(message_unique_receives), 0)) AS click_rate
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily`
+ WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND message_id IS NOT NULL
+ GROUP BY 1, 2, 3, 4, 7
+ HAVING receives >= 10000
+ ORDER BY click_rate DESC, receives DESC
+ LIMIT 25;
+ ```
+
+
+
+## Funnel
+
+
+
+ **What you'll learn:** Daily session-level funnel conversion rates (view item → add to cart → begin checkout → purchase) using distinct-session denominators. Use this for “conversion rate” questions.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=session_funnel_conversion_rates | grain=date | scope=sessions_with_any_funnel_activity
+ WITH events AS (
+ SELECT
+ DATE(event_local_datetime) AS date,
+ COALESCE(event_user_session_id, event_session_id) AS session_id,
+ sm_event_name
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND DATE(event_local_datetime) < CURRENT_DATE()
+ AND (event_user_session_id IS NOT NULL OR event_session_id IS NOT NULL)
+ AND sm_event_name IN ('view_item', 'add_to_cart', 'begin_checkout', 'purchase')
+ ),
+ session_daily AS (
+ SELECT
+ date,
+ session_id,
+ MAX(IF(sm_event_name = 'view_item', 1, 0)) AS has_view_item,
+ MAX(IF(sm_event_name = 'add_to_cart', 1, 0)) AS has_add_to_cart,
+ MAX(IF(sm_event_name = 'begin_checkout', 1, 0)) AS has_begin_checkout,
+ MAX(IF(sm_event_name = 'purchase', 1, 0)) AS has_purchase
+ FROM events
+ GROUP BY 1, 2
+ )
+ SELECT
+ date,
+ COUNT(*) AS sessions,
+ SUM(has_view_item) AS sessions_with_view_item,
+ SUM(has_add_to_cart) AS sessions_with_add_to_cart,
+ SUM(has_begin_checkout) AS sessions_with_begin_checkout,
+ SUM(has_purchase) AS sessions_with_purchase,
+ -- Step conversion rates use *session intersections* so they stay within [0, 1] even if intermediate events are under-tracked.
+ SAFE_DIVIDE(
+ SUM(IF(has_view_item = 1 AND has_add_to_cart = 1, 1, 0)),
+ NULLIF(SUM(has_view_item), 0)
+ ) AS view_to_cart_rate,
+ SAFE_DIVIDE(
+ SUM(IF(has_add_to_cart = 1 AND has_begin_checkout = 1, 1, 0)),
+ NULLIF(SUM(has_add_to_cart), 0)
+ ) AS cart_to_checkout_rate,
+ SAFE_DIVIDE(
+ SUM(IF(has_begin_checkout = 1 AND has_purchase = 1, 1, 0)),
+ NULLIF(SUM(has_begin_checkout), 0)
+ ) AS checkout_to_purchase_rate,
+ SAFE_DIVIDE(SUM(has_purchase), NULLIF(COUNT(*), 0)) AS session_conversion_rate
+ FROM session_daily
+ GROUP BY 1
+ ORDER BY date;
+ ```
+
+
+
+ **What you'll learn:** Which pages have the highest share of sessions that triggered an add-to-cart event on that same page path. Useful for identifying strong product pages/collections and debugging low-performing pages.
+
+ ```sql
+ -- Assumptions: timeframe=last_7_days | metric=on_page_add_to_cart_session_rate | grain=event_page_path | scope=sessions_with_page_path
+ WITH base AS (
+ SELECT
+ event_page_path,
+ COALESCE(event_user_session_id, event_session_id) AS session_id,
+ sm_event_name
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
+ AND DATE(event_local_datetime) < CURRENT_DATE()
+ AND event_page_path IS NOT NULL
+ AND TRIM(event_page_path) != ''
+ AND (event_user_session_id IS NOT NULL OR event_session_id IS NOT NULL)
+ AND sm_event_name IN ('page_view', 'add_to_cart')
+ ),
+ page_session AS (
+ SELECT
+ event_page_path,
+ session_id,
+ MAX(IF(sm_event_name = 'page_view', 1, 0)) AS has_page_view,
+ MAX(IF(sm_event_name = 'add_to_cart', 1, 0)) AS has_add_to_cart
+ FROM base
+ GROUP BY 1, 2
+ )
+ SELECT
+ event_page_path,
+ COUNTIF(has_page_view = 1) AS sessions_with_page_view,
+ COUNTIF(has_page_view = 1 AND has_add_to_cart = 1) AS sessions_with_add_to_cart_on_page,
+ SAFE_DIVIDE(
+ COUNTIF(has_page_view = 1 AND has_add_to_cart = 1),
+ NULLIF(COUNTIF(has_page_view = 1), 0)
+ ) AS add_to_cart_session_rate
+ FROM page_session
+ GROUP BY 1
+ HAVING sessions_with_page_view >= 500
+ ORDER BY add_to_cart_session_rate DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How different acquisition sources/mediums perform through a session-based funnel (distinct-session denominators). This is the recommended pattern for “conversion rate by channel” questions.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=session_funnel_conversion_rates | grain=utm_source_medium | scope=sessions_with_any_funnel_activity
+ -- Notes:
+ -- - Uses DISTINCT sessions (not event-count ratios)
+ -- - UTM source/medium is attributed to the session using the earliest event in that session
+ WITH events AS (
+ SELECT
+ event_local_datetime,
+ COALESCE(event_user_session_id, event_session_id) AS session_id,
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_source)), ''), '(none)') AS utm_source,
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_medium)), ''), '(none)') AS utm_medium,
+ sm_event_name,
+ event_order_revenue
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND DATE(event_local_datetime) < CURRENT_DATE()
+ AND (event_user_session_id IS NOT NULL OR event_session_id IS NOT NULL)
+ ),
+ session_utm AS (
+ SELECT
+ session_id,
+ ARRAY_AGG(utm_source ORDER BY event_local_datetime ASC LIMIT 1)[OFFSET(0)] AS utm_source,
+ ARRAY_AGG(utm_medium ORDER BY event_local_datetime ASC LIMIT 1)[OFFSET(0)] AS utm_medium
+ FROM events
+ GROUP BY 1
+ ),
+ session_steps AS (
+ SELECT
+ session_id,
+ MAX(IF(sm_event_name = 'view_item', 1, 0)) AS has_view_item,
+ MAX(IF(sm_event_name = 'add_to_cart', 1, 0)) AS has_add_to_cart,
+ MAX(IF(sm_event_name = 'begin_checkout', 1, 0)) AS has_begin_checkout,
+ MAX(IF(sm_event_name = 'purchase', 1, 0)) AS has_purchase,
+ SUM(IF(sm_event_name = 'purchase', COALESCE(event_order_revenue, 0), 0)) AS purchase_revenue
+ FROM events
+ GROUP BY 1
+ ),
+ by_channel AS (
+ SELECT
+ CONCAT(u.utm_source, ' / ', u.utm_medium) AS utm_source_medium,
+ s.has_view_item,
+ s.has_add_to_cart,
+ s.has_begin_checkout,
+ s.has_purchase,
+ s.purchase_revenue
+ FROM session_steps s
+ JOIN session_utm u USING (session_id)
+ )
+ SELECT
+ utm_source_medium,
+ COUNT(*) AS sessions,
+ SUM(has_view_item) AS sessions_with_view_item,
+ SUM(has_add_to_cart) AS sessions_with_add_to_cart,
+ SUM(has_begin_checkout) AS sessions_with_begin_checkout,
+ SUM(has_purchase) AS sessions_with_purchase,
+ -- Step conversion rates use *session intersections* so they stay within [0, 1] even if intermediate events are under-tracked.
+ SAFE_DIVIDE(
+ SUM(IF(has_view_item = 1 AND has_add_to_cart = 1, 1, 0)),
+ NULLIF(SUM(has_view_item), 0)
+ ) AS view_to_cart_rate,
+ SAFE_DIVIDE(
+ SUM(IF(has_add_to_cart = 1 AND has_begin_checkout = 1, 1, 0)),
+ NULLIF(SUM(has_add_to_cart), 0)
+ ) AS cart_to_checkout_rate,
+ SAFE_DIVIDE(
+ SUM(IF(has_begin_checkout = 1 AND has_purchase = 1, 1, 0)),
+ NULLIF(SUM(has_begin_checkout), 0)
+ ) AS checkout_to_purchase_rate,
+ SAFE_DIVIDE(SUM(has_purchase), NULLIF(COUNT(*), 0)) AS session_conversion_rate,
+ SUM(purchase_revenue) AS total_revenue
+ FROM by_channel
+ WHERE has_view_item = 1 OR has_add_to_cart = 1 OR has_begin_checkout = 1 OR has_purchase = 1
+ GROUP BY 1
+ HAVING sessions >= 100
+ ORDER BY sessions_with_purchase DESC
+ LIMIT 25;
+ ```
+
+
+ This is a **session-based** funnel. If you want near-real-time monitoring (hourly/daily step volumes and event-based ratios), use [`rpt_funnel_events_performance_hourly`](/data-activation/data-tables/sm_transformed_v2/rpt_funnel_events_performance_hourly).
+
+
+
+
+ **What you'll learn:** Whether one tracking source (`source_system`) appears to be missing critical steps (e.g., begin checkout) relative to other sources. This is a fast “do we have tracking regressions?” check.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=funnel_step_event_counts | grain=source_system | scope=monitoring
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ SUM(page_view_event_count) AS page_views,
+ SUM(view_item_event_count) AS view_item_events,
+ SUM(add_to_cart_event_count) AS add_to_cart_events,
+ SUM(begin_checkout_event_count) AS begin_checkout_events,
+ SUM(purchase_event_count) AS purchase_events
+ FROM `your_project.sm_transformed_v2.rpt_funnel_events_performance_hourly`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ HAVING page_views >= 5000
+ ORDER BY page_views DESC;
+ ```
+
+
+
+ **What you'll learn:** Which tracking sources have unusually large hour-over-hour spikes/drops in purchases. Useful for catching instrumentation outages, batch backfills, or sudden traffic changes.
+
+ ```sql
+ -- Assumptions: timeframe=last_7_days | metric=hour_over_hour_purchase_deltas | grain=hour+source_system | scope=anomaly_triage
+ WITH hourly AS (
+ SELECT
+ event_local_datetime AS hour_start,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ SUM(purchase_event_count) AS purchase_events,
+ SUM(event_order_revenue) AS event_order_revenue
+ FROM `your_project.sm_transformed_v2.rpt_funnel_events_performance_hourly`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
+ GROUP BY 1, 2
+ ),
+ scored AS (
+ SELECT
+ source_system,
+ hour_start,
+ purchase_events,
+ LAG(purchase_events) OVER (PARTITION BY source_system ORDER BY hour_start) AS prev_purchase_events,
+ purchase_events - LAG(purchase_events) OVER (PARTITION BY source_system ORDER BY hour_start) AS delta_purchase_events,
+ SAFE_DIVIDE(
+ purchase_events - LAG(purchase_events) OVER (PARTITION BY source_system ORDER BY hour_start),
+ NULLIF(LAG(purchase_events) OVER (PARTITION BY source_system ORDER BY hour_start), 0)
+ ) AS pct_change_purchase_events,
+ event_order_revenue
+ FROM hourly
+ )
+ SELECT
+ source_system,
+ hour_start,
+ prev_purchase_events,
+ purchase_events,
+ delta_purchase_events,
+ pct_change_purchase_events,
+ event_order_revenue
+ FROM scored
+ WHERE prev_purchase_events >= 10
+ ORDER BY ABS(pct_change_purchase_events) DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Which UTMs drive email signups and purchases (event-based). Useful for diagnosing “lots of leads, few purchases” vs “low leads, high purchases” sources.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=email_signups+purchases | grain=utm_source_medium | scope=event_based
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_source)), ''), '(none)') AS utm_source,
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_medium)), ''), '(none)') AS utm_medium,
+ SUM(email_sign_up_event_count) AS email_signups,
+ SUM(purchase_event_count) AS purchase_events,
+ SUM(event_order_revenue) AS event_order_revenue
+ FROM `your_project.sm_transformed_v2.rpt_funnel_events_performance_hourly`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ CONCAT(utm_source, ' / ', utm_medium) AS utm_source_medium,
+ email_signups,
+ purchase_events,
+ event_order_revenue,
+ SAFE_DIVIDE(event_order_revenue, NULLIF(purchase_events, 0)) AS revenue_per_purchase_event
+ FROM base
+ WHERE email_signups >= 100
+ ORDER BY email_signups DESC
+ LIMIT 50;
+ ```
+
+
+ These are **event-based** counts and ratios (not user-based). Treat them as directional monitoring signals, not conversion attribution.
+
+
+
+
+ **What you'll learn:** Whether remove-from-cart events are spiking relative to add-to-cart, and whether checkout initiation is dropping. Useful for diagnosing UX issues, tracking regressions, or promo-related cart behavior changes.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=cart_drop_off_signals | grain=date | scope=event_based
+ WITH daily AS (
+ SELECT
+ DATE(event_local_datetime) AS date,
+ SUM(add_to_cart_event_count) AS add_to_cart_events,
+ SUM(remove_from_cart_event_count) AS remove_from_cart_events,
+ SUM(begin_checkout_event_count) AS begin_checkout_events,
+ SUM(purchase_event_count) AS purchase_events
+ FROM `your_project.sm_transformed_v2.rpt_funnel_events_performance_hourly`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ )
+ SELECT
+ date,
+ add_to_cart_events,
+ remove_from_cart_events,
+ begin_checkout_events,
+ purchase_events
+ FROM daily
+ ORDER BY date;
+ ```
+
+
+ Remove-from-cart can exceed add-to-cart in event terms (multi-item carts, repeated events). Focus on trend changes, not absolute levels.
+
+
+
+
+## Journeys & Lead Capture
+
+
+These templates use:
+- `sm_transformed_v2.obt_funnel_event_history` for event-level lead capture + timing analysis, and
+- `sm_experimental.obt_purchase_journeys_with_mta_models` for purchase-journey first-touch vs last-touch analysis (MTA).
+
+The MTA tables are **experimental**: treat results as directional and validate against your owned analytics + business context.
+
+
+
+
+ **What you'll learn:** Which normalized funnel events are present in your tenant so you can pick the correct lead-capture event names (email signup, subscribe, generate lead, etc.) without guessing.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=event_counts | grain=event_name | scope=discovery
+ SELECT
+ COALESCE(sm_event_name, '(null)') AS sm_event_name,
+ COUNT(*) AS events
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ ORDER BY events DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** For users who have a lead capture event and later a purchase event, how long it takes to convert (p50/p90 hours), broken out by the UTM source/medium at the lead event.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=lead_to_purchase_timing_hours | grain=lead_utm_source_medium | scope=event_user_id_non_null
+ -- Update this list after running the discovery query above:
+ -- lead_event_names = ('generate_lead', 'sign_up')
+ WITH lead_events AS (
+ SELECT
+ event_user_id,
+ event_local_datetime,
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_source)), ''), '(none)') AS event_utm_source,
+ COALESCE(NULLIF(LOWER(TRIM(event_utm_medium)), ''), '(none)') AS event_utm_medium
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE event_user_id IS NOT NULL
+ AND DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND sm_event_name IN ('generate_lead', 'sign_up')
+ ),
+ first_lead AS (
+ SELECT
+ event_user_id,
+ ARRAY_AGG(STRUCT(event_local_datetime, event_utm_source, event_utm_medium) ORDER BY event_local_datetime ASC LIMIT 1)[OFFSET(0)] AS lead
+ FROM lead_events
+ GROUP BY 1
+ ),
+ first_purchase AS (
+ SELECT
+ event_user_id,
+ MIN(event_local_datetime) AS first_purchase_at
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE event_user_id IS NOT NULL
+ AND DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND sm_event_name = 'purchase'
+ GROUP BY 1
+ ),
+ joined AS (
+ SELECT
+ CONCAT(lead.event_utm_source, ' / ', lead.event_utm_medium) AS lead_utm_source_medium,
+ lead.event_local_datetime AS first_lead_at,
+ p.first_purchase_at,
+ DATETIME_DIFF(p.first_purchase_at, lead.event_local_datetime, HOUR) AS hours_to_first_purchase
+ FROM first_lead l
+ JOIN first_purchase p
+ USING (event_user_id)
+ WHERE p.first_purchase_at >= l.lead.event_local_datetime
+ )
+ SELECT
+ lead_utm_source_medium,
+ COUNT(*) AS purchasers_with_lead_event,
+ APPROX_QUANTILES(hours_to_first_purchase, 101)[OFFSET(50)] AS p50_hours_to_first_purchase,
+ APPROX_QUANTILES(hours_to_first_purchase, 101)[OFFSET(90)] AS p90_hours_to_first_purchase
+ FROM joined
+ GROUP BY 1
+ HAVING purchasers_with_lead_event >= 50
+ ORDER BY purchasers_with_lead_event DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** What share of tracked users with a lead capture event later have a purchase event (identity-based, using DISTINCT `event_user_id`). Useful for directional lead-to-purchase monitoring.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=lead_to_purchase_rate | grain=all_leads | scope=event_user_id_non_null
+ -- Update this list after running the discovery query above:
+ -- lead_event_names = ('generate_lead', 'sign_up')
+ WITH lead_users AS (
+ SELECT DISTINCT
+ event_user_id
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE event_user_id IS NOT NULL
+ AND DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND sm_event_name IN ('generate_lead', 'sign_up')
+ ),
+ purchase_users AS (
+ SELECT DISTINCT
+ event_user_id
+ FROM `your_project.sm_transformed_v2.obt_funnel_event_history`
+ WHERE event_user_id IS NOT NULL
+ AND DATE(event_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND sm_event_name = 'purchase'
+ )
+ SELECT
+ COUNT(DISTINCT l.event_user_id) AS lead_users,
+ COUNT(DISTINCT p.event_user_id) AS purchasers_from_leads,
+ SAFE_DIVIDE(COUNT(DISTINCT p.event_user_id), NULLIF(COUNT(DISTINCT l.event_user_id), 0)) AS lead_to_purchase_rate
+ FROM lead_users l
+ LEFT JOIN purchase_users p
+ USING (event_user_id);
+ ```
+
+
+ This is event-identity based (tracking-user-based), not customer-based. Coverage depends on your tracking setup and identity stitching.
+
+
+
+
+ **What you'll learn:** For purchases, what the **first-touch** vs **last-touch** marketing channels were (journey-level). Useful for quantifying “what brings users in” vs “what closes”.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=purchase_revenue_by_first_last_touch_channel | grain=first_touch+last_touch | scope=mta_purchase_rows_only
+ SELECT
+ COALESCE(first_touch_dimension_value.marketing_channel, '(unknown)') AS first_touch_marketing_channel,
+ COALESCE(last_touch_dimension_value.marketing_channel, '(unknown)') AS last_touch_marketing_channel,
+ COUNT(DISTINCT purchase_order_id) AS orders,
+ SUM(purchase_order_revenue) AS purchase_order_revenue
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE sm_event_name = 'purchase'
+ AND DATE(purchase_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1, 2
+ ORDER BY purchase_order_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** How long it takes to convert by acquisition channel, using MTA-derived days-to-conversion (journey-level).
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=days_to_conversion | grain=first_touch_marketing_channel | scope=mta_purchase_rows_only
+ WITH purchases AS (
+ SELECT
+ COALESCE(first_touch_dimension_value.marketing_channel, '(unknown)') AS first_touch_marketing_channel,
+ CAST(days_to_conversion.marketing_channel AS INT64) AS days_to_conversion_marketing_channel
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE sm_event_name = 'purchase'
+ AND DATE(purchase_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND days_to_conversion.marketing_channel IS NOT NULL
+ )
+ SELECT
+ first_touch_marketing_channel,
+ COUNT(*) AS purchases,
+ AVG(days_to_conversion_marketing_channel) AS avg_days_to_conversion,
+ APPROX_QUANTILES(days_to_conversion_marketing_channel, 101)[OFFSET(50)] AS p50_days_to_conversion,
+ APPROX_QUANTILES(days_to_conversion_marketing_channel, 101)[OFFSET(90)] AS p90_days_to_conversion
+ FROM purchases
+ GROUP BY 1
+ HAVING purchases >= 100
+ ORDER BY purchases DESC;
+ ```
+
+
+
+ **What you'll learn:** Which landing pages most often appear as the **first-touch landing page** for purchases, and the associated revenue impact (directional).
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=first_touch_landing_page_revenue | grain=landing_page | scope=mta_purchase_rows_only
+ SELECT
+ COALESCE(NULLIF(dimension_value.landing_page, ''), '(unknown)') AS first_touch_landing_page,
+ COUNT(DISTINCT purchase_order_id) AS orders,
+ SUM(purchase_order_revenue) AS purchase_order_revenue,
+ SUM(first_touch_revenue_impact.landing_page) AS first_touch_attributed_revenue_landing_page
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE DATE(purchase_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND first_touch_revenue_impact.landing_page > 0
+ GROUP BY 1
+ ORDER BY first_touch_attributed_revenue_landing_page DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** What customers say drove their purchase (post‑purchase survey tags), and how it differs for new vs repeat orders and subscription orders.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=zero_party_source+new_repeat+subscription_sequence | scope=valid_orders_only
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_zero_party_attribution_source)), ''), '(none)') AS sm_zero_party_attribution_source,
+ sm_valid_order_sequence,
+ subscription_order_sequence,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ GROUP BY 1, 2, 3
+ ORDER BY order_net_revenue DESC
+ LIMIT 100;
+ ```
+
+
+
+ **What you'll learn:** How last-click orders attributed to Klaviyo perform, segmented by new vs repeat and subscription sequence. This uses `sm_utm_source/sm_utm_medium` (last-click) from the order attribution hierarchy.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=utm_medium+new_repeat+subscription_sequence | scope=valid_orders_only_last_click_utm
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_medium)), ''), '(none)') AS sm_utm_medium,
+ sm_valid_order_sequence,
+ subscription_order_sequence,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND LOWER(TRIM(sm_utm_source)) = 'klaviyo'
+ AND LOWER(TRIM(sm_utm_medium)) IN ('email', 'sms')
+ GROUP BY 1, 2, 3
+ ORDER BY order_net_revenue DESC;
+ ```
+
+
+ If you don’t see `sm_utm_source = 'klaviyo'` in your tenant, run the “UTM source/medium discovery” template and choose the exact source values for your messaging stack.
+
+
+
+
+## Customers & Retention
+
+
+
+ **What you'll learn:** The split between customers’ **first valid order** vs repeat valid orders in terms of order count, unique customers, and net revenue. Track this over time to understand how much revenue comes from retention vs new customer acquisition.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=orders+customers+net_revenue | grain=first_vs_repeat | scope=valid_orders_only
+ SELECT
+ CASE WHEN sm_valid_order_index = 1 THEN 'first_valid_order' ELSE 'repeat_valid_order' END AS order_type,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ COUNT(DISTINCT sm_customer_key) AS customers,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ ORDER BY orders DESC;
+ ```
+
+
+
+ **What you'll learn:** Which acquisition channels bring in customers who come back to buy again. Identify your best sources for long-term customer value versus one-time buyers.
+
+ ```sql
+ -- Assumptions: timeframe=first_orders_last_12_months | metric=repeat_rate=customers_with_2+_orders/customers | grain=first_order_source_medium | scope=valid_orders_only
+ WITH valid_orders AS (
+ SELECT
+ sm_customer_key,
+ sm_order_key,
+ order_processed_at_local_datetime,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ ROW_NUMBER() OVER (
+ PARTITION BY sm_customer_key
+ ORDER BY order_processed_at_local_datetime
+ ) AS rn
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ ),
+ customer_summary AS (
+ SELECT
+ sm_customer_key,
+ MAX(CASE WHEN rn = 1 THEN source_medium END) AS first_order_source_medium,
+ MIN(CASE WHEN rn = 1 THEN DATE(order_processed_at_local_datetime) END) AS first_order_date,
+ COUNT(DISTINCT sm_order_key) AS valid_order_count
+ FROM valid_orders
+ GROUP BY 1
+ )
+ SELECT
+ first_order_source_medium AS source_medium,
+ COUNT(*) AS customers,
+ COUNTIF(valid_order_count >= 2) AS repeat_customers,
+ SAFE_DIVIDE(COUNTIF(valid_order_count >= 2), COUNT(*)) AS repeat_rate,
+ AVG(valid_order_count - 1) AS avg_subsequent_orders
+ FROM customer_summary
+ WHERE first_order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ GROUP BY 1
+ HAVING customers >= 100
+ ORDER BY repeat_rate DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How your balance between new and returning customers has shifted week-over-week this year. Use this to see whether acquisition is outpacing repeat purchasing (or vice versa), and to spot meaningful shifts after campaigns or seasonality.
+
+ ```sql
+ -- Assumptions: timeframe=year_to_date | metric=new_to_repeat_ratio=new_customer_count/repeat_customer_count | grain=week | scope=all_channels
+ WITH weekly AS (
+ SELECT
+ DATE_TRUNC(date, WEEK(MONDAY)) AS week_start,
+ SUM(new_customer_count) AS new_customers,
+ SUM(repeat_customer_count) AS repeat_customers
+ FROM `your_project.sm_transformed_v2.rpt_executive_summary_daily`
+ WHERE date >= DATE_TRUNC(CURRENT_DATE(), YEAR)
+ GROUP BY 1
+ )
+ SELECT
+ week_start,
+ new_customers,
+ repeat_customers,
+ SAFE_DIVIDE(new_customers, NULLIF(repeat_customers, 0)) AS new_to_repeat_ratio
+ FROM weekly
+ ORDER BY week_start;
+ ```
+
+
+
+ **What you'll learn:** Your month-over-month new customer growth including order count, revenue, and average order value from first-time buyers. Use this to track whether your acquisition efforts are scaling.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_months | metric=new_customers | grain=month | scope=all_channels
+ WITH monthly AS (
+ SELECT
+ DATE_TRUNC(date, MONTH) AS month_start,
+ SUM(new_customer_count) AS new_customers,
+ SUM(new_customer_order_count) AS new_customer_orders,
+ SUM(new_customer_order_net_revenue) AS new_customer_order_net_revenue
+ FROM `your_project.sm_transformed_v2.rpt_executive_summary_daily`
+ WHERE date >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ GROUP BY 1
+ )
+ SELECT
+ month_start,
+ new_customers,
+ new_customer_orders,
+ new_customer_order_net_revenue,
+ SAFE_DIVIDE(new_customer_order_net_revenue, NULLIF(new_customer_orders, 0)) AS new_customer_aov
+ FROM monthly
+ ORDER BY month_start;
+ ```
+
+
+
+## Products
+
+
+
+ **What you'll learn:** Your highest revenue-generating products with units sold and order counts. Use this to identify your cash cows and prioritize inventory, marketing, and merchandising decisions.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=net_revenue=SUM(order_line_net_revenue) | grain=sku | scope=valid_orders_only
+ SELECT
+ sku,
+ ANY_VALUE(product_title) AS product_title,
+ SUM(order_line_net_revenue) AS order_line_net_revenue,
+ SUM(order_line_quantity) AS units_sold,
+ COUNT(DISTINCT sm_order_key) AS orders
+ FROM `your_project.sm_transformed_v2.obt_order_lines`
+ WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1
+ ORDER BY order_line_net_revenue DESC
+ LIMIT 10;
+ ```
+
+
+
+ **What you'll learn:** Your most popular products by volume, which may differ from your top revenue generators. Useful for forecasting demand, managing inventory levels, and identifying viral or gateway products.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=units_sold=SUM(order_line_quantity) | grain=sku | scope=valid_orders_only
+ SELECT
+ sku,
+ ANY_VALUE(product_title) AS product_title,
+ SUM(order_line_quantity) AS units_sold,
+ SUM(order_line_net_revenue) AS order_line_net_revenue,
+ COUNT(DISTINCT sm_order_key) AS orders
+ FROM `your_project.sm_transformed_v2.obt_order_lines`
+ WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1
+ ORDER BY units_sold DESC
+ LIMIT 20;
+ ```
+
+
+
+ **What you'll learn:** Which products are most often the entry point for new customers. These "gateway products" are key to acquisition strategy—consider featuring them in ads, bundles, or welcome offers.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_90_days | metric=units_sold=SUM(order_line_quantity) | grain=product_title | scope=new_customers_valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_order_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ )
+ SELECT
+ ol.product_title,
+ SUM(ol.order_line_quantity) AS units_sold,
+ COUNT(DISTINCT ol.sm_order_key) AS orders,
+ COUNT(DISTINCT ol.sku) AS skus
+ FROM `your_project.sm_transformed_v2.obt_order_lines` ol
+ INNER JOIN first_valid_orders fvo
+ ON ol.sm_order_key = fvo.sm_order_key
+ WHERE ol.is_order_sm_valid = TRUE
+ AND ol.sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1
+ ORDER BY units_sold DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Which products are frequently purchased together in the same order. Use this for bundle recommendations, cross-sell strategies, and merchandising decisions.
+
+ ```sql
+ -- Assumptions: timeframe=all_time | metric=order_frequency | grain=product_combination | scope=valid_orders_only
+ WITH RECURSIVE product_combos AS (
+ -- Anchor: Start with individual products per order
+ SELECT
+ ol.sm_store_id,
+ ol.sm_order_key,
+ 1 AS combo_length,
+ CONCAT(ol.product_title, ' - ', ol.product_variant_title) AS combo,
+ CONCAT(ol.product_title, ' - ', ol.product_variant_title) AS last_item
+ FROM `your_project.sm_transformed_v2.obt_order_lines` AS ol
+ WHERE ol.sm_store_id = 'your-sm_store_id'
+ AND ol.is_order_sm_valid = TRUE
+ AND ol.sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee|order specific)')
+
+ UNION ALL
+
+ -- Recursive: Build combinations up to 5 products
+ SELECT
+ ol.sm_store_id,
+ ol.sm_order_key,
+ pc.combo_length + 1,
+ CONCAT(pc.combo, ', ', CONCAT(ol.product_title, ' - ', ol.product_variant_title)),
+ CONCAT(ol.product_title, ' - ', ol.product_variant_title)
+ FROM product_combos AS pc
+ INNER JOIN `your_project.sm_transformed_v2.obt_order_lines` AS ol
+ ON ol.sm_order_key = pc.sm_order_key
+ AND CONCAT(ol.product_title, ' - ', ol.product_variant_title) > pc.last_item
+ WHERE pc.combo_length < 5
+ AND ol.is_order_sm_valid = TRUE
+ AND ol.sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee|order specific)')
+ )
+
+ SELECT
+ combo AS product_combinations,
+ COUNT(DISTINCT sm_order_key) AS order_frequency,
+ combo_length AS num_products
+ FROM product_combos
+ WHERE combo_length >= 2
+ GROUP BY combo, combo_length
+ HAVING order_frequency >= 100
+ ORDER BY order_frequency DESC, combo ASC
+ LIMIT 100;
+ ```
+
+
+
+## Orders & Revenue
+
+
+
+ **What you'll learn:** Which marketing channels drive higher-value orders. Channels with high AOV may warrant more budget even if volume is lower; low-AOV channels might need different offer strategies.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=AOV=SUM(order_net_revenue)/orders | grain=sm_utm_source_medium | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS marketing_channel,
+ sm_order_key,
+ sm_customer_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ )
+ SELECT
+ marketing_channel,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ COUNT(DISTINCT sm_customer_key) AS customers,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(SUM(order_net_revenue), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS aov
+ FROM base
+ GROUP BY 1
+ HAVING orders >= 50
+ ORDER BY aov DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** How much of your recent revenue comes from customers with subscription history (even if they're not currently subscribed). Helps quantify the long-term value of your subscription program.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=net_revenue=SUM(order_net_revenue) | grain=overall | scope=customers_with_any_subscription_history
+ WITH subscription_customers AS (
+ SELECT DISTINCT
+ sm_customer_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND is_subscription_order = TRUE
+ AND sm_customer_key IS NOT NULL
+ ),
+ last_30_valid_orders AS (
+ SELECT
+ sm_order_key,
+ sm_customer_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND sm_customer_key IS NOT NULL
+ )
+ SELECT
+ SUM(CASE WHEN sc.sm_customer_key IS NOT NULL THEN o.order_net_revenue ELSE 0 END) AS revenue_from_customers_with_subscription_history,
+ SUM(o.order_net_revenue) AS total_revenue_last_30_days,
+ SAFE_DIVIDE(
+ SUM(CASE WHEN sc.sm_customer_key IS NOT NULL THEN o.order_net_revenue ELSE 0 END),
+ NULLIF(SUM(o.order_net_revenue), 0)
+ ) AS pct_of_revenue_from_subscription_history_customers
+ FROM last_30_valid_orders o
+ LEFT JOIN subscription_customers sc
+ ON o.sm_customer_key = sc.sm_customer_key;
+ ```
+
+
+
+ **What you'll learn:** Which marketing channels have higher refund rates—by order count and by revenue. High refund rates may indicate mismatched expectations from certain ad campaigns or audiences.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=refund_rate | grain=sm_utm_source_medium | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS marketing_channel,
+ order_total_refunds,
+ order_net_revenue_before_refunds,
+ sm_order_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ )
+ SELECT
+ marketing_channel,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ COUNTIF(ABS(order_total_refunds) > 0) AS refunded_orders,
+ SAFE_DIVIDE(COUNTIF(ABS(order_total_refunds) > 0), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS refund_rate_orders,
+ ABS(SUM(order_total_refunds)) AS refund_amount,
+ SUM(order_net_revenue_before_refunds) AS revenue_before_refunds,
+ SAFE_DIVIDE(ABS(SUM(order_total_refunds)), NULLIF(SUM(order_net_revenue_before_refunds), 0)) AS refund_rate_revenue
+ FROM base
+ GROUP BY 1
+ HAVING orders >= 50
+ ORDER BY refund_rate_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** How your orders and revenue are distributed across different sales channels (online, POS, wholesale, etc.). Useful for understanding channel mix and identifying growth opportunities.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=orders+net_revenue+share | grain=sm_channel | scope=valid_orders_only
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_channel)), ''), '(unknown)') AS sm_channel,
+ COUNT(*) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(COUNT(*), NULLIF(SUM(COUNT(*)) OVER (), 0)) AS pct_orders,
+ SAFE_DIVIDE(SUM(order_net_revenue), NULLIF(SUM(SUM(order_net_revenue)) OVER (), 0)) AS pct_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ ORDER BY orders DESC;
+ ```
+
+
+
+## LTV & Retention
+
+These templates cover cohort analysis, payback periods, and repeat purchase behavior. Some use the pre-aggregated cohort table for efficiency.
+
+
+If you use the cohort LTV table (`rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`):
+- Always filter **one** cohort dimension (e.g., `acquisition_order_filter_dimension = 'source/medium'`)
+- Always include `sm_order_line_type = 'all_orders'` unless you explicitly want a subset
+
+
+
+
+ **What you'll learn:** Which cohort dimensions are available in the LTV table. Run this first to see what you can filter by (e.g., `source/medium`, `discount_code`, `order_type_(sub_vs._one_time)`).
+
+ ```sql
+ -- Assumptions: timeframe=all_time | metric=discovery | grain=acquisition_order_filter_dimension | scope=cohort_table_only
+ SELECT DISTINCT
+ acquisition_order_filter_dimension
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ ORDER BY 1;
+ ```
+
+
+
+ **What you'll learn:** Which acquisition sources produce customers with the best retention and lifetime value at the 3 and 6 month marks. Use this to optimize ad spend toward channels that deliver long-term value, not just initial conversions.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_cohort_months | metric=retention_pct+ltv_6m | grain=source_medium | scope=cohort_table_all_orders
+ WITH pivoted AS (
+ SELECT
+ acquisition_order_filter_dimension_value AS source_medium,
+ cohort_month,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ MAX(IF(months_since_first_order = 3, customer_count, NULL)) AS customers_m3,
+ MAX(IF(months_since_first_order = 6, customer_count, NULL)) AS customers_m6,
+ MAX(IF(months_since_first_order = 6, cumulative_order_net_revenue, NULL)) AS cumulative_order_net_revenue_m6
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'source/medium'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ AND months_since_first_order IN (3, 6)
+ GROUP BY 1, 2
+ )
+ SELECT
+ source_medium,
+ SUM(cohort_size) AS cohort_customers,
+ SAFE_DIVIDE(SUM(customers_m3), NULLIF(SUM(cohort_size), 0)) AS retention_m3,
+ SAFE_DIVIDE(SUM(customers_m6), NULLIF(SUM(cohort_size), 0)) AS retention_m6,
+ SAFE_DIVIDE(SUM(cumulative_order_net_revenue_m6), NULLIF(SUM(cohort_size), 0)) AS ltv_net_per_customer_m6
+ FROM pivoted
+ GROUP BY 1
+ HAVING cohort_customers >= 200
+ ORDER BY retention_m6 DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Roughly how many **months** it takes for each acquisition source/medium cohort to “pay back” its CAC (when cohort cumulative net revenue per customer first exceeds `cost_per_acquisition`). Only interpret rows where your cohort model populates CAC for that cohort.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_cohort_months | metric=payback_months | grain=source_medium | scope=cohort_table_all_orders
+ WITH base AS (
+ SELECT
+ acquisition_order_filter_dimension_value AS source_medium,
+ cohort_month,
+ months_since_first_order,
+ cohort_size,
+ cost_per_acquisition,
+ cumulative_order_net_revenue
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'source/medium'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ AND months_since_first_order BETWEEN 0 AND 12
+ AND cost_per_acquisition IS NOT NULL
+ AND cost_per_acquisition > 0
+ ),
+ per_cohort AS (
+ SELECT
+ source_medium,
+ cohort_month,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ ANY_VALUE(cost_per_acquisition) AS cac_per_customer,
+ MIN(
+ IF(
+ SAFE_DIVIDE(cumulative_order_net_revenue, NULLIF(cohort_size, 0)) >= cost_per_acquisition,
+ months_since_first_order,
+ NULL
+ )
+ ) AS payback_months
+ FROM base
+ GROUP BY 1, 2
+ )
+ SELECT
+ source_medium,
+ SUM(cohort_size) AS cohort_customers,
+ SAFE_DIVIDE(
+ SUM(CAST(payback_months AS FLOAT64) * cohort_size),
+ NULLIF(SUM(CASE WHEN payback_months IS NOT NULL THEN cohort_size ELSE 0 END), 0)
+ ) AS avg_payback_months_weighted,
+ SAFE_DIVIDE(
+ SUM(CASE WHEN payback_months IS NOT NULL THEN cohort_size ELSE 0 END),
+ NULLIF(SUM(cohort_size), 0)
+ ) AS pct_customers_in_cohorts_with_payback_within_12m
+ FROM per_cohort
+ GROUP BY 1
+ HAVING cohort_customers >= 200
+ ORDER BY avg_payback_months_weighted ASC;
+ ```
+
+
+
+ **What you'll learn:** Whether you’re getting enough 6‑month net revenue per acquired customer relative to CAC (a simple **LTV:CAC** sanity check). Only interpret rows where your cohort model populates CAC for that cohort.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_cohort_months | metric=ltv_to_cac_ratio_6m | grain=source_medium | scope=cohort_table_all_orders
+ WITH per_cohort AS (
+ SELECT
+ acquisition_order_filter_dimension_value AS source_medium,
+ cohort_month,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ ANY_VALUE(cost_per_acquisition) AS cac_per_customer,
+ MAX(IF(months_since_first_order = 6, cumulative_order_net_revenue, NULL)) AS cumulative_order_net_revenue_m6
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'source/medium'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ AND months_since_first_order = 6
+ AND cost_per_acquisition IS NOT NULL
+ AND cost_per_acquisition > 0
+ GROUP BY 1, 2
+ )
+ SELECT
+ source_medium,
+ SUM(cohort_size) AS cohort_customers,
+ SAFE_DIVIDE(SUM(cumulative_order_net_revenue_m6), NULLIF(SUM(cohort_size), 0)) AS ltv_net_per_customer_m6,
+ SAFE_DIVIDE(SUM(cac_per_customer * cohort_size), NULLIF(SUM(cohort_size), 0)) AS cac_per_customer_weighted,
+ SAFE_DIVIDE(
+ SAFE_DIVIDE(SUM(cumulative_order_net_revenue_m6), NULLIF(SUM(cohort_size), 0)),
+ NULLIF(SAFE_DIVIDE(SUM(cac_per_customer * cohort_size), NULLIF(SUM(cohort_size), 0)), 0)
+ ) AS ltv_to_cac_ratio_m6
+ FROM per_cohort
+ GROUP BY 1
+ HAVING cohort_customers >= 200
+ ORDER BY ltv_to_cac_ratio_m6 DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Which discount codes attract customers who stick around and spend more over time. Identify promo codes that bring loyal buyers vs. one-time bargain hunters.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_cohort_months | metric=retention_m6+ltv_12m | grain=discount_code | scope=cohort_table_all_orders
+ WITH pivoted AS (
+ SELECT
+ acquisition_order_filter_dimension_value AS discount_code,
+ cohort_month,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ MAX(IF(months_since_first_order = 6, customer_count, NULL)) AS customers_m6,
+ MAX(IF(months_since_first_order = 12, cumulative_order_net_revenue, NULL)) AS cumulative_order_net_revenue_m12
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'discount_code'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ AND months_since_first_order IN (6, 12)
+ AND acquisition_order_filter_dimension_value IS NOT NULL
+ AND acquisition_order_filter_dimension_value != ''
+ GROUP BY 1, 2
+ ),
+ aggregated AS (
+ SELECT
+ discount_code,
+ SUM(cohort_size) AS cohort_customers,
+ SAFE_DIVIDE(SUM(customers_m6), NULLIF(SUM(cohort_size), 0)) AS retention_m6,
+ SAFE_DIVIDE(SUM(cumulative_order_net_revenue_m12), NULLIF(SUM(cohort_size), 0)) AS ltv_net_per_customer_m12
+ FROM pivoted
+ GROUP BY 1
+ HAVING cohort_customers >= 100
+ )
+ SELECT
+ discount_code,
+ cohort_customers,
+ retention_m6,
+ ltv_net_per_customer_m12
+ FROM aggregated
+ ORDER BY ltv_net_per_customer_m12 DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How customers who start with a subscription compare to one-time buyers in terms of retention and lifetime value. Quantify the LTV advantage (or disadvantage) of your subscription program.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_cohort_months | metric=retention_m6+ltv_12m | grain=first_order_type | scope=cohort_table_all_orders
+ WITH pivoted AS (
+ SELECT
+ acquisition_order_filter_dimension_value AS first_order_type,
+ cohort_month,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ MAX(IF(months_since_first_order = 6, customer_count, NULL)) AS customers_m6,
+ MAX(IF(months_since_first_order = 12, cumulative_order_net_revenue, NULL)) AS cumulative_order_net_revenue_m12
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'order_type_(sub_vs._one_time)'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 12 MONTH)
+ AND months_since_first_order IN (6, 12)
+ GROUP BY 1, 2
+ )
+ SELECT
+ first_order_type,
+ SUM(cohort_size) AS cohort_customers,
+ SAFE_DIVIDE(SUM(customers_m6), NULLIF(SUM(cohort_size), 0)) AS retention_m6,
+ SAFE_DIVIDE(SUM(cumulative_order_net_revenue_m12), NULLIF(SUM(cohort_size), 0)) AS ltv_net_per_customer_m12
+ FROM pivoted
+ GROUP BY 1
+ HAVING cohort_customers >= 50
+ ORDER BY ltv_net_per_customer_m12 DESC;
+ ```
+
+
+
+ **What you'll learn:** How quickly customers come back to buy again after their first valid purchase, broken out by acquisition source/medium. This version counts only repeat orders with `order_net_revenue > 0` (so $0 replacements/comp orders don’t inflate “purchase” rates).
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=repeat_rate_30_60_90 | grain=source_medium | scope=valid_paid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ per_customer AS (
+ SELECT
+ fo.source_medium,
+ fo.sm_customer_key,
+ MIN(DATETIME_DIFF(o.order_processed_at_local_datetime, fo.first_order_at_local_datetime, DAY)) AS first_repeat_day,
+ COUNT(DISTINCT o.sm_order_key) AS repeat_orders_90d,
+ COALESCE(SUM(o.order_net_revenue), 0) AS repeat_revenue_90d
+ FROM first_valid_orders fo
+ LEFT JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ AND o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_net_revenue > 0
+ AND o.order_processed_at_local_datetime > fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ source_medium,
+ COUNT(*) AS customers,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30) AS customers_repeat_30d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30), NULLIF(COUNT(*), 0)) AS repeat_rate_30d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60) AS customers_repeat_60d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60), NULLIF(COUNT(*), 0)) AS repeat_rate_60d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90) AS customers_repeat_90d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90), NULLIF(COUNT(*), 0)) AS repeat_rate_90d,
+ AVG(repeat_orders_90d) AS avg_repeat_orders_90d,
+ AVG(repeat_revenue_90d) AS avg_repeat_revenue_90d
+ FROM per_customer
+ GROUP BY 1
+ HAVING customers >= 200
+ ORDER BY repeat_rate_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** A practical retention proxy for subscription programs: customers whose **first valid order** was subscription vs one-time, and how quickly they return to buy again. This version counts only repeat orders with `order_net_revenue > 0`.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=repeat_rate_30_60_90 | grain=first_order_type | scope=valid_paid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ CASE
+ WHEN is_subscription_order = TRUE THEN 'subscription_first_order'
+ ELSE 'one_time_first_order'
+ END AS first_order_type
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ per_customer AS (
+ SELECT
+ fo.first_order_type,
+ fo.sm_customer_key,
+ MIN(DATETIME_DIFF(o.order_processed_at_local_datetime, fo.first_order_at_local_datetime, DAY)) AS first_repeat_day,
+ COUNT(DISTINCT o.sm_order_key) AS repeat_orders_90d,
+ COALESCE(SUM(o.order_net_revenue), 0) AS repeat_revenue_90d
+ FROM first_valid_orders fo
+ LEFT JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ AND o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_net_revenue > 0
+ AND o.order_processed_at_local_datetime > fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ first_order_type,
+ COUNT(*) AS customers,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30) AS customers_repeat_30d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30), NULLIF(COUNT(*), 0)) AS repeat_rate_30d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60) AS customers_repeat_60d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60), NULLIF(COUNT(*), 0)) AS repeat_rate_60d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90) AS customers_repeat_90d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90), NULLIF(COUNT(*), 0)) AS repeat_rate_90d,
+ AVG(repeat_orders_90d) AS avg_repeat_orders_90d,
+ AVG(repeat_revenue_90d) AS avg_repeat_revenue_90d
+ FROM per_customer
+ GROUP BY 1
+ HAVING customers >= 200
+ ORDER BY repeat_rate_90d DESC;
+ ```
+
+
+
+ **What you'll learn:** Whether high-AOV first purchases actually translate into better short-term retention. This version counts only repeat orders with `order_net_revenue > 0` so that $0 orders don’t inflate “purchase” rates.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=repeat_rate_30_60_90 | grain=first_order_aov_bucket | scope=valid_paid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ order_net_revenue AS first_order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ bucketed AS (
+ SELECT
+ sm_customer_key,
+ first_order_at_local_datetime,
+ CASE
+ WHEN first_order_net_revenue < 25 THEN '$0–$25'
+ WHEN first_order_net_revenue < 50 THEN '$25–$50'
+ WHEN first_order_net_revenue < 100 THEN '$50–$100'
+ WHEN first_order_net_revenue < 200 THEN '$100–$200'
+ ELSE '$200+'
+ END AS first_order_aov_bucket
+ FROM first_valid_orders
+ ),
+ per_customer AS (
+ SELECT
+ b.first_order_aov_bucket,
+ b.sm_customer_key,
+ MIN(DATETIME_DIFF(o.order_processed_at_local_datetime, b.first_order_at_local_datetime, DAY)) AS first_repeat_day,
+ COUNT(DISTINCT o.sm_order_key) AS repeat_orders_90d,
+ COALESCE(SUM(o.order_net_revenue), 0) AS repeat_revenue_90d
+ FROM bucketed b
+ LEFT JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = b.sm_customer_key
+ AND o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_net_revenue > 0
+ AND o.order_processed_at_local_datetime > b.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(b.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ first_order_aov_bucket,
+ COUNT(*) AS customers,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30) AS customers_repeat_30d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 30), NULLIF(COUNT(*), 0)) AS repeat_rate_30d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60) AS customers_repeat_60d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 60), NULLIF(COUNT(*), 0)) AS repeat_rate_60d,
+ COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90) AS customers_repeat_90d,
+ SAFE_DIVIDE(COUNTIF(first_repeat_day IS NOT NULL AND first_repeat_day <= 90), NULLIF(COUNT(*), 0)) AS repeat_rate_90d,
+ AVG(repeat_orders_90d) AS avg_repeat_orders_90d,
+ AVG(repeat_revenue_90d) AS avg_repeat_revenue_90d
+ FROM per_customer
+ GROUP BY 1
+ ORDER BY CASE first_order_aov_bucket
+ WHEN '$0–$25' THEN 1
+ WHEN '$25–$50' THEN 2
+ WHEN '$50–$100' THEN 3
+ WHEN '$100–$200' THEN 4
+ WHEN '$200+' THEN 5
+ ELSE 99
+ END;
+ ```
+
+
+
+ **What you'll learn:** Which acquisition source/mediums produce higher 90‑day LTV (including the first order). This is a dynamic alternative to cohort tables when you want a strict “first purchase → next 90 days” window.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV | grain=first_order_source_medium | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS first_order_source_medium
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ fo.first_order_source_medium,
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ first_order_source_medium AS source_medium,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM customer_90d_ltv
+ GROUP BY 1
+ HAVING customers >= 200
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How 90‑day LTV differs for customers whose first valid order used **exactly one** discount code vs no code. Customers whose first order has multiple codes are excluded to avoid ambiguity/double counting. Use the “Multiple discount codes prevalence” diagnostic before interpreting results.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV | grain=first_order_discount_code | scope=valid_orders_only_single_or_no_code
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ order_discount_codes_csv
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ parsed_codes AS (
+ SELECT
+ sm_customer_key,
+ first_order_at_local_datetime,
+ ARRAY(
+ SELECT LOWER(TRIM(code_raw))
+ FROM UNNEST(SPLIT(COALESCE(order_discount_codes_csv, ''), ',')) AS code_raw
+ WHERE TRIM(code_raw) != ''
+ AND LOWER(TRIM(code_raw)) NOT IN ('(none)')
+ ) AS codes
+ FROM first_valid_orders
+ ),
+ cohort AS (
+ SELECT
+ sm_customer_key,
+ first_order_at_local_datetime,
+ ARRAY_LENGTH(codes) AS code_count,
+ IF(ARRAY_LENGTH(codes) = 1, codes[OFFSET(0)], '(no_code)') AS first_order_discount_code
+ FROM parsed_codes
+ WHERE ARRAY_LENGTH(codes) IN (0, 1)
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ c.first_order_discount_code,
+ c.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM cohort c
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = c.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= c.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(c.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2
+ )
+ SELECT
+ first_order_discount_code AS discount_code,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM customer_90d_ltv
+ GROUP BY 1
+ HAVING customers >= 50
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Which acquisition source/mediums produce higher refund rates on the **first valid order** (by order count and by revenue). This is a common “traffic quality” question and helps spot channels driving mismatched expectations.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=first_order_refund_rate | grain=first_order_source_medium | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ sm_order_key,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS first_order_source_medium,
+ order_total_refunds,
+ order_net_revenue_before_refunds
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ )
+ SELECT
+ first_order_source_medium AS source_medium,
+ COUNT(DISTINCT sm_order_key) AS first_orders,
+ COUNTIF(ABS(order_total_refunds) > 0) AS refunded_first_orders,
+ SAFE_DIVIDE(COUNTIF(ABS(order_total_refunds) > 0), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS refund_rate_orders,
+ ABS(SUM(order_total_refunds)) AS refund_amount,
+ SUM(order_net_revenue_before_refunds) AS revenue_before_refunds,
+ SAFE_DIVIDE(ABS(SUM(order_total_refunds)), NULLIF(SUM(order_net_revenue_before_refunds), 0)) AS refund_rate_revenue
+ FROM first_valid_orders
+ GROUP BY 1
+ HAVING first_orders >= 200
+ ORDER BY refund_rate_revenue DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** How 90‑day LTV differs by the commerce platform (`source_system`) and sales channel (`sm_channel`) of the first valid order. This helps separate marketplace/POS behavior from online DTC without mixing attribution concepts.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV | grain=first_order_source_system+sm_channel | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS first_order_source_system,
+ COALESCE(NULLIF(LOWER(TRIM(sm_channel)), ''), '(unknown)') AS first_order_sm_channel
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ fo.first_order_source_system,
+ fo.first_order_sm_channel,
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1, 2, 3
+ )
+ SELECT
+ first_order_source_system AS source_system,
+ first_order_sm_channel AS sm_channel,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM customer_90d_ltv
+ GROUP BY 1, 2
+ HAVING customers >= 200
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** A sanity check to reconcile precomputed cohort-table LTV (month-offset based) with a dynamic 180-day LTV window from `obt_orders`. Differences can indicate mismatched cohort definitions or expectation gaps (month buckets vs day windows).
+
+ ```sql
+ -- Assumptions: timeframe=last_6_cohort_months | metric=ltv_reconciliation | grain=cohort_month+source_medium | scope=cohort_table_vs_dynamic
+ WITH cohort_table AS (
+ SELECT
+ cohort_month,
+ COALESCE(NULLIF(LOWER(TRIM(acquisition_order_filter_dimension_value)), ''), '(none) / (none)') AS source_medium,
+ ANY_VALUE(cohort_size) AS cohort_size,
+ MAX(IF(months_since_first_order = 6, cumulative_order_net_revenue, NULL)) AS cumulative_order_net_revenue_m6
+ FROM `your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ WHERE acquisition_order_filter_dimension = 'source/medium'
+ AND sm_order_line_type = 'all_orders'
+ AND cohort_month >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 6 MONTH)
+ AND months_since_first_order = 6
+ GROUP BY 1, 2
+ ),
+ first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime,
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), MONTH) AS cohort_month,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 6 MONTH)
+ ),
+ dynamic_180d AS (
+ SELECT
+ fo.cohort_month,
+ fo.source_medium,
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_180d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 180 DAY)
+ GROUP BY 1, 2, 3
+ ),
+ dynamic_rollup AS (
+ SELECT
+ cohort_month,
+ source_medium,
+ COUNT(*) AS cohort_customers_dynamic,
+ AVG(ltv_180d) AS ltv_net_per_customer_180d
+ FROM dynamic_180d
+ GROUP BY 1, 2
+ )
+ SELECT
+ d.cohort_month,
+ d.source_medium,
+ d.cohort_customers_dynamic,
+ d.ltv_net_per_customer_180d,
+ c.cohort_size AS cohort_customers_table,
+ SAFE_DIVIDE(c.cumulative_order_net_revenue_m6, NULLIF(c.cohort_size, 0)) AS ltv_net_per_customer_m6,
+ d.ltv_net_per_customer_180d - SAFE_DIVIDE(c.cumulative_order_net_revenue_m6, NULLIF(c.cohort_size, 0)) AS diff_dynamic_minus_table,
+ SAFE_DIVIDE(
+ d.ltv_net_per_customer_180d - SAFE_DIVIDE(c.cumulative_order_net_revenue_m6, NULLIF(c.cohort_size, 0)),
+ NULLIF(SAFE_DIVIDE(c.cumulative_order_net_revenue_m6, NULLIF(c.cohort_size, 0)), 0)
+ ) AS pct_diff_dynamic_vs_table
+ FROM dynamic_rollup d
+ LEFT JOIN cohort_table c
+ ON d.cohort_month = c.cohort_month
+ AND d.source_medium = c.source_medium
+ WHERE d.cohort_customers_dynamic >= 200
+ ORDER BY ABS(pct_diff_dynamic_vs_table) DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Which **primary first‑order SKU** (one SKU per customer, chosen as the highest net‑revenue line item on the first valid order) is associated with higher 90‑day LTV. Use this to identify “starter products” to feature in acquisition campaigns and new customer bundles.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV=SUM(order_net_revenue_90d) | grain=primary_first_sku | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ sm_order_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ first_order_primary_sku AS (
+ SELECT
+ fo.sm_customer_key,
+ ol.sku,
+ ANY_VALUE(ol.product_title) AS product_title,
+ SUM(ol.order_line_net_revenue) AS first_order_sku_net_revenue
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_order_lines` ol
+ ON ol.sm_order_key = fo.sm_order_key
+ WHERE ol.is_order_sm_valid = TRUE
+ AND ol.sku IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1, 2
+ QUALIFY ROW_NUMBER() OVER (
+ PARTITION BY fo.sm_customer_key
+ ORDER BY first_order_sku_net_revenue DESC
+ ) = 1
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1
+ )
+ SELECT
+ pos.sku,
+ pos.product_title,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM first_order_primary_sku pos
+ INNER JOIN customer_90d_ltv ltv
+ ON pos.sm_customer_key = ltv.sm_customer_key
+ GROUP BY 1, 2
+ HAVING customers >= 20
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Which **product types** tend to create higher 90‑day customer value when they appear as the “primary” first-order item (one product type per customer, selected by highest first-order net revenue). This is a scalable alternative to SKU-level LTV.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV | grain=primary_first_product_type | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ sm_order_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ first_order_primary_product_type AS (
+ SELECT
+ fo.sm_customer_key,
+ COALESCE(NULLIF(LOWER(TRIM(ol.product_type)), ''), '(unknown)') AS product_type,
+ SUM(ol.order_line_net_revenue) AS first_order_type_net_revenue
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_order_lines` ol
+ ON ol.sm_order_key = fo.sm_order_key
+ WHERE ol.is_order_sm_valid = TRUE
+ AND ol.product_type IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1, 2
+ QUALIFY ROW_NUMBER() OVER (
+ PARTITION BY fo.sm_customer_key
+ ORDER BY first_order_type_net_revenue DESC
+ ) = 1
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1
+ )
+ SELECT
+ pt.product_type,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM first_order_primary_product_type pt
+ INNER JOIN customer_90d_ltv ltv
+ ON pt.sm_customer_key = ltv.sm_customer_key
+ GROUP BY 1
+ HAVING customers >= 50
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** Which **vendors** tend to create higher 90‑day customer value when they appear as the “primary” first-order item (one vendor per customer, selected by highest first-order net revenue). Useful for wholesale/brand partnerships and merchandising.
+
+ ```sql
+ -- Assumptions: timeframe=first_valid_orders_last_12_months | metric=90d_LTV | grain=primary_first_product_vendor | scope=valid_orders_only
+ WITH first_valid_orders AS (
+ SELECT
+ sm_customer_key,
+ sm_order_key,
+ order_processed_at_local_datetime AS first_order_at_local_datetime
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_valid_order_index = 1
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ first_order_primary_vendor AS (
+ SELECT
+ fo.sm_customer_key,
+ COALESCE(NULLIF(LOWER(TRIM(ol.product_vendor)), ''), '(unknown)') AS product_vendor,
+ SUM(ol.order_line_net_revenue) AS first_order_vendor_net_revenue
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_order_lines` ol
+ ON ol.sm_order_key = fo.sm_order_key
+ WHERE ol.is_order_sm_valid = TRUE
+ AND ol.product_vendor IS NOT NULL
+ AND NOT REGEXP_CONTAINS(ol.product_title, r'(?i)(shipping protection|not a product|service fee|processing fee)')
+ GROUP BY 1, 2
+ QUALIFY ROW_NUMBER() OVER (
+ PARTITION BY fo.sm_customer_key
+ ORDER BY first_order_vendor_net_revenue DESC
+ ) = 1
+ ),
+ customer_90d_ltv AS (
+ SELECT
+ fo.sm_customer_key,
+ SUM(o.order_net_revenue) AS ltv_90d
+ FROM first_valid_orders fo
+ INNER JOIN `your_project.sm_transformed_v2.obt_orders` o
+ ON o.sm_customer_key = fo.sm_customer_key
+ WHERE o.is_order_sm_valid = TRUE
+ AND o.order_cancelled_at IS NULL
+ AND o.order_processed_at_local_datetime >= fo.first_order_at_local_datetime
+ AND o.order_processed_at_local_datetime < DATETIME_ADD(fo.first_order_at_local_datetime, INTERVAL 90 DAY)
+ GROUP BY 1
+ )
+ SELECT
+ v.product_vendor,
+ COUNT(*) AS customers,
+ AVG(ltv_90d) AS avg_ltv_90d,
+ SUM(ltv_90d) AS total_ltv_90d
+ FROM first_order_primary_vendor v
+ INNER JOIN customer_90d_ltv ltv
+ ON v.sm_customer_key = ltv.sm_customer_key
+ GROUP BY 1
+ HAVING customers >= 50
+ ORDER BY avg_ltv_90d DESC
+ LIMIT 25;
+ ```
+
+
+
+ **What you'll learn:** The distribution of days between repeat purchases for non-subscription customers. Use this to time your re-engagement emails and identify the optimal window for replenishment reminders.
+
+ ```sql
+ -- Assumptions: timeframe=last_12_months | metric=days_between_orders_distribution | grain=days_between_orders | scope=non_subscription_customers_only
+ WITH subscription_customers AS (
+ SELECT DISTINCT
+ sm_customer_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND is_subscription_order = TRUE
+ AND sm_customer_key IS NOT NULL
+ ),
+ non_subscription_orders AS (
+ SELECT
+ sm_customer_key,
+ DATE(order_processed_at_local_datetime) AS order_date
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND sm_customer_key IS NOT NULL
+ AND sm_customer_key NOT IN (SELECT sm_customer_key FROM subscription_customers)
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
+ ),
+ per_customer_gaps AS (
+ SELECT
+ sm_customer_key,
+ order_date,
+ DATE_DIFF(
+ order_date,
+ LAG(order_date) OVER (PARTITION BY sm_customer_key ORDER BY order_date),
+ DAY
+ ) AS days_since_prior_order
+ FROM non_subscription_orders
+ )
+ SELECT
+ days_since_prior_order,
+ COUNT(*) AS repeat_order_pairs
+ FROM per_customer_gaps
+ WHERE days_since_prior_order IS NOT NULL
+ AND days_since_prior_order BETWEEN 1 AND 365
+ GROUP BY 1
+ ORDER BY days_since_prior_order;
+ ```
+
+
+
+## Attribution & Data Health
+
+These templates help you assess attribution coverage and basic data health before doing deeper analysis.
+
+If you want table-level freshness/coverage metadata, start with: [`dim_data_dictionary`](/data-activation/data-tables/sm_metadata/dim_data_dictionary).
+
+
+
+ **What you'll learn:** Which tables in your data warehouse haven't been updated recently or are missing data entirely. Run this first to identify pipeline issues before diving into analysis.
+
+ ```sql
+ -- Assumptions: timeframe=all_time | metric=table_freshness | grain=dataset+table | scope=sm_metadata
+ SELECT
+ dataset_name,
+ table_name,
+ MAX(CAST(table_has_data AS INT64)) > 0 AS table_has_data,
+ MAX(CAST(table_has_fresh_data_14d AS INT64)) > 0 AS table_has_fresh_data_14d,
+ MAX(table_last_data_date) AS table_last_data_date,
+ ANY_VALUE(table_description) AS table_description
+ FROM `your_project.sm_metadata.dim_data_dictionary`
+ WHERE dataset_name IN ('sm_transformed_v2', 'sm_experimental')
+ AND dataset_name IS NOT NULL
+ AND table_name IS NOT NULL
+ GROUP BY 1, 2
+ ORDER BY table_has_fresh_data_14d ASC, table_has_data ASC, table_last_data_date ASC, dataset_name, table_name
+ LIMIT 200;
+ ```
+
+
+
+ **What you'll learn:** How complete your attribution data is—what percentage of orders have UTM source, zero-party attribution, discount codes, landing pages, and referrer domains. Low coverage in key columns signals tracking gaps.
+
+ ```sql
+ -- Assumptions: timeframe=all_time | metric=column_coverage | grain=column | scope=sm_metadata_obt_orders
+ WITH cols AS (
+ SELECT 'sm_utm_source' AS column_name UNION ALL
+ SELECT 'sm_utm_medium' UNION ALL
+ SELECT 'sm_utm_source_medium' UNION ALL
+ SELECT 'sm_zero_party_attribution_source' UNION ALL
+ SELECT 'order_discount_codes_csv' UNION ALL
+ SELECT 'sm_order_landing_page' UNION ALL
+ SELECT 'sm_order_referrer_domain'
+ )
+ SELECT
+ d.table_name,
+ d.column_name,
+ ROUND(100 - d.column_null_percentage, 1) AS non_null_pct,
+ d.column_distinct_count,
+ (
+ SELECT STRING_AGG(
+ CONCAT(v.value, ' (', FORMAT('%.1f', v.pct), '%)'),
+ ', '
+ ORDER BY v.pct DESC
+ LIMIT 8
+ )
+ FROM UNNEST(IFNULL(d.categorical_value_distribution, [])) AS v
+ WHERE v.value IS NOT NULL AND v.pct IS NOT NULL
+ ) AS top_values
+ FROM `your_project.sm_metadata.dim_data_dictionary` d
+ INNER JOIN cols c
+ ON d.column_name = c.column_name
+ WHERE d.dataset_name = 'sm_transformed_v2'
+ AND d.table_name = 'obt_orders'
+ ORDER BY non_null_pct DESC, d.column_distinct_count DESC, d.column_name;
+ ```
+
+
+
+ **What you'll learn:** For orders without UTM tracking, what fallback attribution data is available (zero-party surveys, discount codes, landing pages, referrer domains). Helps you understand how much attribution you can recover.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=fallback_coverage | grain=overall | scope=valid_orders_only_missing_utms
+ WITH missing_utms AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ sm_zero_party_attribution_source,
+ order_discount_codes_csv,
+ sm_order_landing_page,
+ sm_order_referrer_domain
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') = '(none) / (none)'
+ )
+ SELECT
+ COUNT(DISTINCT sm_order_key) AS orders_missing_utms,
+ SUM(order_net_revenue) AS order_net_revenue_missing_utms,
+ COUNTIF(sm_zero_party_attribution_source IS NOT NULL AND TRIM(sm_zero_party_attribution_source) NOT IN ('', '(none)')) AS orders_with_zero_party,
+ SAFE_DIVIDE(
+ COUNTIF(sm_zero_party_attribution_source IS NOT NULL AND TRIM(sm_zero_party_attribution_source) NOT IN ('', '(none)')),
+ NULLIF(COUNT(DISTINCT sm_order_key), 0)
+ ) AS pct_with_zero_party,
+ COUNTIF(order_discount_codes_csv IS NOT NULL AND TRIM(order_discount_codes_csv) NOT IN ('', '(none)')) AS orders_with_discount_code,
+ SAFE_DIVIDE(
+ COUNTIF(order_discount_codes_csv IS NOT NULL AND TRIM(order_discount_codes_csv) NOT IN ('', '(none)')),
+ NULLIF(COUNT(DISTINCT sm_order_key), 0)
+ ) AS pct_with_discount_code,
+ COUNTIF(sm_order_landing_page IS NOT NULL AND TRIM(sm_order_landing_page) NOT IN ('', '(none)')) AS orders_with_landing_page,
+ SAFE_DIVIDE(
+ COUNTIF(sm_order_landing_page IS NOT NULL AND TRIM(sm_order_landing_page) NOT IN ('', '(none)')),
+ NULLIF(COUNT(DISTINCT sm_order_key), 0)
+ ) AS pct_with_landing_page,
+ COUNTIF(sm_order_referrer_domain IS NOT NULL AND TRIM(sm_order_referrer_domain) NOT IN ('', '(none)')) AS orders_with_referrer_domain,
+ SAFE_DIVIDE(
+ COUNTIF(sm_order_referrer_domain IS NOT NULL AND TRIM(sm_order_referrer_domain) NOT IN ('', '(none)')),
+ NULLIF(COUNT(DISTINCT sm_order_key), 0)
+ ) AS pct_with_referrer_domain
+ FROM missing_utms;
+ ```
+
+
+
+ **What you'll learn:** Which external sites are sending you traffic that isn't tagged with UTMs. Use this to identify partners, affiliates, or other untracked sources that need proper tracking or attribution rules.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=referrer_domain | scope=valid_orders_only_missing_utms
+ WITH base AS (
+ SELECT
+ LOWER(TRIM(sm_order_referrer_domain)) AS referrer_domain,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') = '(none) / (none)'
+ AND sm_order_referrer_domain IS NOT NULL
+ AND TRIM(sm_order_referrer_domain) NOT IN ('', '(none)')
+ )
+ SELECT
+ referrer_domain,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM base
+ GROUP BY 1
+ HAVING orders >= 25
+ ORDER BY order_net_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** The percentage of orders missing customer keys and order lines missing SKUs. Critical for data integrity—high null rates here break customer-level analysis and product reporting.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=null_rate_checks | grain=overall | scope=valid_orders_only
+ WITH orders AS (
+ SELECT
+ COUNT(*) AS orders_total,
+ COUNTIF(sm_customer_key IS NULL) AS orders_missing_customer_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ ),
+ lines AS (
+ SELECT
+ COUNT(*) AS lines_total,
+ COUNTIF(sku IS NULL OR TRIM(sku) = '' OR LOWER(sku) = 'missing sku') AS lines_missing_sku
+ FROM `your_project.sm_transformed_v2.obt_order_lines`
+ WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ )
+ SELECT
+ orders_total,
+ orders_missing_customer_key,
+ SAFE_DIVIDE(orders_missing_customer_key, NULLIF(orders_total, 0)) AS pct_orders_missing_customer_key,
+ lines_total,
+ lines_missing_sku,
+ SAFE_DIVIDE(lines_missing_sku, NULLIF(lines_total, 0)) AS pct_lines_missing_sku
+ FROM orders
+ CROSS JOIN lines;
+ ```
+
+
+
+ **What you'll learn:** How your attribution coverage has changed week-over-week—UTM coverage, unattributed orders, and direct traffic share. Spot tracking regressions or improvements over time.
+
+ ```sql
+ -- Assumptions: timeframe=last_26_weeks | metric=utm_coverage+direct_share+unattributed_share | grain=week | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 182 DAY)
+ ),
+ weekly AS (
+ SELECT
+ week_start,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ COUNTIF(source_medium = '(none) / (none)') AS unattributed_orders,
+ SUM(CASE WHEN source_medium = '(none) / (none)' THEN order_net_revenue ELSE 0 END) AS unattributed_revenue,
+ COUNTIF(source_medium IN ('(direct) / (none)', 'direct / (none)')) AS direct_orders,
+ SUM(CASE WHEN source_medium IN ('(direct) / (none)', 'direct / (none)') THEN order_net_revenue ELSE 0 END) AS direct_revenue,
+ COUNTIF(source_medium != '(none) / (none)') AS orders_with_utm_source_medium
+ FROM base
+ GROUP BY 1
+ )
+ SELECT
+ week_start,
+ orders,
+ order_net_revenue,
+ SAFE_DIVIDE(orders_with_utm_source_medium, NULLIF(orders, 0)) AS pct_orders_with_utm_source_medium,
+ SAFE_DIVIDE(unattributed_orders, NULLIF(orders, 0)) AS pct_orders_unattributed,
+ SAFE_DIVIDE(unattributed_revenue, NULLIF(order_net_revenue, 0)) AS pct_revenue_unattributed,
+ SAFE_DIVIDE(direct_orders, NULLIF(orders, 0)) AS pct_orders_direct,
+ SAFE_DIVIDE(direct_revenue, NULLIF(order_net_revenue, 0)) AS pct_revenue_direct
+ FROM weekly
+ ORDER BY week_start;
+ ```
+
+
+
+ **What you'll learn:** How attribution coverage varies across your stores and sales channels (online vs. POS vs. wholesale). Some channels naturally have lower attribution—this helps set expectations.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=unattributed_share | grain=sm_store_id+sm_channel | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ sm_store_id,
+ COALESCE(NULLIF(LOWER(TRIM(sm_channel)), ''), '(unknown)') AS sm_channel,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND NULLIF(LOWER(TRIM(sm_channel)), '') IS NOT NULL
+ )
+ SELECT
+ sm_store_id,
+ sm_channel,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(COUNTIF(source_medium = '(none) / (none)'), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_orders_unattributed,
+ SAFE_DIVIDE(
+ SUM(CASE WHEN source_medium = '(none) / (none)' THEN order_net_revenue ELSE 0 END),
+ NULLIF(SUM(order_net_revenue), 0)
+ ) AS pct_revenue_unattributed
+ FROM base
+ GROUP BY 1, 2
+ HAVING orders >= 50
+ ORDER BY pct_revenue_unattributed DESC, orders DESC
+ LIMIT 100;
+ ```
+
+
+
+ **What you'll learn:** Your top discount codes ranked by revenue, with order counts and AOV. Use this to evaluate promo effectiveness and identify codes that might be over-used or under-attributed.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=discount_code | scope=valid_orders_only
+ -- Note: If an order has multiple discount codes, its revenue will be counted under each code (this is a code-usage view, not strict attribution).
+ WITH orders_with_codes AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ order_discount_codes_csv
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND order_discount_codes_csv IS NOT NULL
+ AND TRIM(order_discount_codes_csv) != ''
+ ),
+ exploded AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ TRIM(code_raw) AS discount_code
+ FROM orders_with_codes,
+ UNNEST(SPLIT(order_discount_codes_csv, ',')) AS code_raw
+ WHERE TRIM(code_raw) != ''
+ )
+ SELECT
+ discount_code,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(SUM(order_net_revenue), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS aov
+ FROM exploded
+ GROUP BY 1
+ HAVING orders >= 25
+ ORDER BY order_net_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Which pages customers land on when they arrive without UTM tracking. Useful for identifying untracked entry points and pages that need better tracking implementation.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=landing_host+landing_path | scope=valid_orders_only_missing_utms
+ WITH base AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ sm_order_landing_page
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') = '(none) / (none)'
+ AND sm_order_landing_page IS NOT NULL
+ AND TRIM(sm_order_landing_page) NOT IN ('', '(none)')
+ ),
+ parsed AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ REGEXP_EXTRACT(sm_order_landing_page, r'^(?:https?://)?([^/?#]+)') AS landing_host,
+ REGEXP_EXTRACT(sm_order_landing_page, r'^(?:https?://)?[^/?#]+(/[^?#]*)') AS landing_path
+ FROM base
+ )
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(landing_host)), ''), '(unknown)') AS landing_host,
+ COALESCE(NULLIF(landing_path, ''), '/') AS landing_path,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM parsed
+ GROUP BY 1, 2
+ HAVING orders >= 25
+ ORDER BY order_net_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** The overlap between UTM tracking and ad-platform click IDs (gclid for Google, fbclid for Meta). Reveals orders where click IDs exist but UTMs don't—potential attribution recovery opportunities.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=utm_coverage+click_id_coverage | grain=week | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ sm_order_key,
+ order_net_revenue,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_gclid,
+ sm_fbclid
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ )
+ SELECT
+ week_start,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ COUNTIF(source_medium != '(none) / (none)') AS orders_with_utm_source_medium,
+ SAFE_DIVIDE(COUNTIF(source_medium != '(none) / (none)'), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_orders_with_utm_source_medium,
+ COUNTIF(sm_gclid IS NOT NULL AND sm_gclid NOT IN ('', '(none)')) AS orders_with_gclid,
+ SAFE_DIVIDE(COUNTIF(sm_gclid IS NOT NULL AND sm_gclid NOT IN ('', '(none)')), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_orders_with_gclid,
+ COUNTIF(sm_fbclid IS NOT NULL AND sm_fbclid NOT IN ('', '(none)')) AS orders_with_fbclid,
+ SAFE_DIVIDE(COUNTIF(sm_fbclid IS NOT NULL AND sm_fbclid NOT IN ('', '(none)')), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_orders_with_fbclid,
+ COUNTIF(source_medium = '(none) / (none)' AND sm_gclid IS NOT NULL AND sm_gclid NOT IN ('', '(none)')) AS utm_missing_but_gclid_orders,
+ COUNTIF(source_medium = '(none) / (none)' AND sm_fbclid IS NOT NULL AND sm_fbclid NOT IN ('', '(none)')) AS utm_missing_but_fbclid_orders
+ FROM base
+ GROUP BY 1
+ ORDER BY week_start;
+ ```
+
+
+
+
+These are deeper-dive investigations for when attribution looks “weird” (too much direct/unattributed), or when downstream metrics are being skewed by edge-case orders.
+
+
+
+
+ **What you'll learn:** Which source/mediums have an unusually high share of valid orders with `order_net_revenue = 0` (or negative). This often indicates replacements/comp orders or heavy discounts that can skew repeat/retention metrics.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=paid_vs_zero_vs_negative_order_share | grain=source_medium | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ )
+ SELECT
+ source_medium,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ COUNTIF(order_net_revenue > 0) AS paid_orders,
+ SAFE_DIVIDE(COUNTIF(order_net_revenue > 0), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_paid_orders,
+ COUNTIF(order_net_revenue = 0) AS zero_net_revenue_orders,
+ SAFE_DIVIDE(COUNTIF(order_net_revenue = 0), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_zero_net_revenue_orders,
+ COUNTIF(order_net_revenue < 0) AS negative_net_revenue_orders,
+ SAFE_DIVIDE(COUNTIF(order_net_revenue < 0), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_negative_net_revenue_orders
+ FROM base
+ GROUP BY 1
+ HAVING orders >= 200
+ ORDER BY pct_zero_net_revenue_orders DESC, orders DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Where unattributed orders are coming from by commerce platform (`source_system`) and sales channel (`sm_channel`). Some channels (e.g., marketplaces or POS) naturally have lower UTM coverage—this helps separate “expected” vs “broken tracking.”
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=unattributed_share | grain=source_system+sm_channel | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ COALESCE(NULLIF(LOWER(TRIM(sm_channel)), ''), '(unknown)') AS sm_channel,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND NULLIF(LOWER(TRIM(source_system)), '') IS NOT NULL
+ AND NULLIF(LOWER(TRIM(sm_channel)), '') IS NOT NULL
+ )
+ SELECT
+ source_system,
+ sm_channel,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ COUNTIF(source_medium = '(none) / (none)') AS unattributed_orders,
+ SAFE_DIVIDE(COUNTIF(source_medium = '(none) / (none)'), NULLIF(COUNT(DISTINCT sm_order_key), 0)) AS pct_orders_unattributed,
+ SAFE_DIVIDE(
+ SUM(CASE WHEN source_medium = '(none) / (none)' THEN order_net_revenue ELSE 0 END),
+ NULLIF(SUM(order_net_revenue), 0)
+ ) AS pct_revenue_unattributed
+ FROM base
+ GROUP BY 1, 2
+ HAVING orders >= 200
+ ORDER BY pct_revenue_unattributed DESC, orders DESC
+ LIMIT 100;
+ ```
+
+
+
+ **What you'll learn:** Which landing pages are most associated with “direct” orders (based on `sm_utm_source_medium`)—and whether landing page capture is missing. This helps diagnose tracking gaps (e.g., missing UTMs or missing landing-page capture on key entry flows).
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=landing_host+landing_path | scope=valid_orders_only_direct
+ WITH base AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ NULLIF(TRIM(sm_order_landing_page), '') AS sm_order_landing_page
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') IN ('(direct) / (none)', 'direct / (none)')
+ ),
+ parsed AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ REGEXP_EXTRACT(sm_order_landing_page, r'^(?:https?://)?([^/?#]+)') AS landing_host,
+ REGEXP_EXTRACT(sm_order_landing_page, r'^(?:https?://)?[^/?#]+(/[^?#]*)') AS landing_path
+ FROM base
+ )
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(landing_host)), ''), '(missing_landing_page)') AS landing_host,
+ COALESCE(NULLIF(landing_path, ''), '(missing_landing_page)') AS landing_path,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue
+ FROM parsed
+ GROUP BY 1, 2
+ HAVING orders >= 25
+ ORDER BY order_net_revenue DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** A “tracking regression detector”: week-over-week changes in unattributed/direct order share and revenue share. Sudden jumps typically indicate tagging/measurement changes.
+
+ ```sql
+ -- Assumptions: timeframe=last_26_weeks | metric=utm_coverage+direct_share+unattributed_share+wow_deltas | grain=week | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 182 DAY)
+ ),
+ weekly AS (
+ SELECT
+ week_start,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ COUNTIF(source_medium = '(none) / (none)') AS unattributed_orders,
+ SUM(CASE WHEN source_medium = '(none) / (none)' THEN order_net_revenue ELSE 0 END) AS unattributed_revenue,
+ COUNTIF(source_medium IN ('(direct) / (none)', 'direct / (none)')) AS direct_orders,
+ SUM(CASE WHEN source_medium IN ('(direct) / (none)', 'direct / (none)') THEN order_net_revenue ELSE 0 END) AS direct_revenue,
+ COUNTIF(source_medium != '(none) / (none)') AS orders_with_utm_source_medium
+ FROM base
+ GROUP BY 1
+ ),
+ metrics AS (
+ SELECT
+ week_start,
+ orders,
+ order_net_revenue,
+ SAFE_DIVIDE(orders_with_utm_source_medium, NULLIF(orders, 0)) AS pct_orders_with_utm_source_medium,
+ SAFE_DIVIDE(unattributed_orders, NULLIF(orders, 0)) AS pct_orders_unattributed,
+ SAFE_DIVIDE(unattributed_revenue, NULLIF(order_net_revenue, 0)) AS pct_revenue_unattributed,
+ SAFE_DIVIDE(direct_orders, NULLIF(orders, 0)) AS pct_orders_direct,
+ SAFE_DIVIDE(direct_revenue, NULLIF(order_net_revenue, 0)) AS pct_revenue_direct
+ FROM weekly
+ )
+ SELECT
+ week_start,
+ orders,
+ order_net_revenue,
+ pct_orders_with_utm_source_medium,
+ pct_orders_unattributed,
+ pct_orders_unattributed - LAG(pct_orders_unattributed) OVER (ORDER BY week_start) AS delta_pct_orders_unattributed,
+ pct_revenue_unattributed,
+ pct_revenue_unattributed - LAG(pct_revenue_unattributed) OVER (ORDER BY week_start) AS delta_pct_revenue_unattributed,
+ pct_orders_direct,
+ pct_orders_direct - LAG(pct_orders_direct) OVER (ORDER BY week_start) AS delta_pct_orders_direct,
+ pct_revenue_direct,
+ pct_revenue_direct - LAG(pct_revenue_direct) OVER (ORDER BY week_start) AS delta_pct_revenue_direct
+ FROM metrics
+ ORDER BY week_start;
+ ```
+
+
+
+ **What you'll learn:** What your UTM `source/medium` values actually look like in practice (normalized with `LOWER(TRIM())`). Use this to discover the exact strings you should filter on—without guessing.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=orders+net_revenue | grain=source_medium | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source_medium)), ''), '(none) / (none)') AS source_medium,
+ sm_order_key,
+ order_net_revenue
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ )
+ SELECT
+ source_medium,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(COUNT(DISTINCT sm_order_key), NULLIF(SUM(COUNT(DISTINCT sm_order_key)) OVER (), 0)) AS pct_orders,
+ SAFE_DIVIDE(SUM(order_net_revenue), NULLIF(SUM(SUM(order_net_revenue)) OVER (), 0)) AS pct_revenue
+ FROM base
+ GROUP BY 1
+ ORDER BY orders DESC
+ LIMIT 50;
+ ```
+
+
+
+ **What you'll learn:** Whether key join fields are getting worse over time. Spikes in missing `sm_customer_key` (orders) or missing `sku` (order lines) will break customer-level and product-level analysis.
+
+ ```sql
+ -- Assumptions: timeframe=last_26_weeks | metric=missing_key_trends | grain=week | scope=valid_orders_only
+ WITH orders_weekly AS (
+ SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ COUNT(*) AS orders_total,
+ COUNTIF(sm_customer_key IS NULL) AS orders_missing_customer_key
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 182 DAY)
+ GROUP BY 1
+ ),
+ lines_weekly AS (
+ SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ COUNT(*) AS lines_total,
+ COUNTIF(sku IS NULL OR TRIM(sku) = '' OR LOWER(sku) = 'missing sku') AS lines_missing_sku
+ FROM `your_project.sm_transformed_v2.obt_order_lines`
+ WHERE is_order_sm_valid = TRUE
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 182 DAY)
+ GROUP BY 1
+ )
+ SELECT
+ o.week_start,
+ o.orders_total,
+ o.orders_missing_customer_key,
+ SAFE_DIVIDE(o.orders_missing_customer_key, NULLIF(o.orders_total, 0)) AS pct_orders_missing_customer_key,
+ l.lines_total,
+ l.lines_missing_sku,
+ SAFE_DIVIDE(l.lines_missing_sku, NULLIF(l.lines_total, 0)) AS pct_lines_missing_sku
+ FROM orders_weekly o
+ LEFT JOIN lines_weekly l
+ USING (week_start)
+ ORDER BY o.week_start;
+ ```
+
+
+
+ **What you'll learn:** How often orders have multiple discount codes applied. This matters because any “revenue by discount code” view will double-count revenue across codes when multiple codes exist.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=discount_code_multiplicity | grain=code_count_bucket | scope=valid_orders_only
+ WITH base AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ order_discount_codes_csv
+ FROM `your_project.sm_transformed_v2.obt_orders`
+ WHERE is_order_sm_valid = TRUE
+ AND order_cancelled_at IS NULL
+ AND DATE(order_processed_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND order_discount_codes_csv IS NOT NULL
+ AND TRIM(order_discount_codes_csv) NOT IN ('', '(none)')
+ ),
+ code_counts AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ ARRAY_LENGTH(
+ ARRAY(
+ SELECT TRIM(code_raw)
+ FROM UNNEST(SPLIT(order_discount_codes_csv, ',')) AS code_raw
+ WHERE TRIM(code_raw) != ''
+ )
+ ) AS code_count
+ FROM base
+ ),
+ bucketed AS (
+ SELECT
+ sm_order_key,
+ order_net_revenue,
+ LEAST(code_count, 5) AS code_count_bucket
+ FROM code_counts
+ )
+ SELECT
+ CASE code_count_bucket
+ WHEN 5 THEN '5+'
+ ELSE CAST(code_count_bucket AS STRING)
+ END AS code_count_bucket,
+ COUNT(DISTINCT sm_order_key) AS orders,
+ SAFE_DIVIDE(COUNT(DISTINCT sm_order_key), NULLIF(SUM(COUNT(DISTINCT sm_order_key)) OVER (), 0)) AS pct_orders,
+ SUM(order_net_revenue) AS order_net_revenue,
+ SAFE_DIVIDE(SUM(order_net_revenue), NULLIF(SUM(SUM(order_net_revenue)) OVER (), 0)) AS pct_revenue
+ FROM bucketed
+ GROUP BY 1, code_count_bucket
+ ORDER BY code_count_bucket;
+ ```
+
+
+
+## Customer Support
+
+
+
+ **What you'll learn:** How ticket volume and one-touch resolution varies by support channel (email, chat, Instagram DM, etc.). Use this to identify which channels are driving the most workload and where your team is resolving issues efficiently.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=ticket_volume+one_touch_rate | grain=communication_channel | scope=exclude_spam
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(ticket_communication_channel)), ''), '(unknown)') AS ticket_communication_channel,
+ COUNT(DISTINCT sm_ticket_key) AS tickets,
+ COUNTIF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'open') AS open_tickets,
+ COUNTIF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'closed') AS closed_tickets,
+ COUNTIF(is_ticket_one_touch = TRUE) AS one_touch_tickets,
+ SAFE_DIVIDE(COUNTIF(is_ticket_one_touch = TRUE), NULLIF(COUNT(DISTINCT sm_ticket_key), 0)) AS one_touch_rate
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND DATE(ticket_created_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1
+ ORDER BY tickets DESC;
+ ```
+
+
+
+ **What you'll learn:** Which teams are closing tickets fastest and how complete your CSAT data is by team. Use this for staffing, training, and process improvement.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=resolution_time_hours+csat_coverage | grain=assignee_team | scope=closed_tickets_exclude_spam
+ SELECT
+ COALESCE(NULLIF(TRIM(ticket_assignee_team_name), ''), '(unassigned)') AS ticket_assignee_team_name,
+ COUNT(DISTINCT sm_ticket_key) AS closed_tickets,
+ AVG(ticket_resolution_time_hours) AS avg_resolution_time_hours,
+ APPROX_QUANTILES(ticket_resolution_time_hours, 101)[OFFSET(50)] AS p50_resolution_time_hours,
+ APPROX_QUANTILES(ticket_resolution_time_hours, 101)[OFFSET(90)] AS p90_resolution_time_hours,
+ COUNTIF(ticket_csat_score IS NOT NULL) AS csat_responses,
+ SAFE_DIVIDE(COUNTIF(ticket_csat_score IS NOT NULL), NULLIF(COUNT(DISTINCT sm_ticket_key), 0)) AS csat_response_rate,
+ AVG(ticket_csat_score) AS avg_csat_score
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND ticket_resolution_time_hours IS NOT NULL
+ AND ticket_status IS NOT NULL
+ AND LOWER(ticket_status) = 'closed'
+ AND DATE(ticket_created_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ GROUP BY 1
+ HAVING closed_tickets >= 25
+ ORDER BY avg_resolution_time_hours ASC;
+ ```
+
+
+
+ **What you'll learn:** How old your open ticket backlog is (age buckets + p50/p90) broken out by team and channel. Useful for backlog management and escalation.
+
+ ```sql
+ -- Assumptions: timeframe=current_state | metric=open_ticket_age_buckets | grain=team+channel | scope=open_tickets_exclude_spam
+ WITH open_tickets AS (
+ SELECT
+ COALESCE(NULLIF(TRIM(ticket_assignee_team_name), ''), '(unassigned)') AS ticket_assignee_team_name,
+ COALESCE(NULLIF(LOWER(TRIM(ticket_communication_channel)), ''), '(unknown)') AS ticket_communication_channel,
+ DATE_DIFF(CURRENT_DATE(), DATE(ticket_created_at_local_datetime), DAY) AS ticket_age_days
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND ticket_status IS NOT NULL
+ AND LOWER(ticket_status) = 'open'
+ AND ticket_created_at_local_datetime IS NOT NULL
+ )
+ SELECT
+ ticket_assignee_team_name,
+ ticket_communication_channel,
+ COUNT(*) AS open_tickets,
+ COUNTIF(ticket_age_days = 0) AS age_0d,
+ COUNTIF(ticket_age_days BETWEEN 1 AND 2) AS age_1_2d,
+ COUNTIF(ticket_age_days BETWEEN 3 AND 6) AS age_3_6d,
+ COUNTIF(ticket_age_days BETWEEN 7 AND 13) AS age_7_13d,
+ COUNTIF(ticket_age_days >= 14) AS age_14d_plus,
+ APPROX_QUANTILES(ticket_age_days, 101)[OFFSET(50)] AS p50_ticket_age_days,
+ APPROX_QUANTILES(ticket_age_days, 101)[OFFSET(90)] AS p90_ticket_age_days
+ FROM open_tickets
+ GROUP BY 1, 2
+ HAVING COUNT(*) >= 25
+ ORDER BY open_tickets DESC;
+ ```
+
+
+
+ **What you'll learn:** Which teams/channels have the highest unread share of open tickets. Useful for triage and staffing.
+
+ ```sql
+ -- Assumptions: timeframe=current_state | metric=unread_open_ticket_share | grain=team+channel | scope=open_tickets_exclude_spam
+ SELECT
+ COALESCE(NULLIF(TRIM(ticket_assignee_team_name), ''), '(unassigned)') AS ticket_assignee_team_name,
+ COALESCE(NULLIF(LOWER(TRIM(ticket_communication_channel)), ''), '(unknown)') AS ticket_communication_channel,
+ COUNT(DISTINCT sm_ticket_key) AS open_tickets,
+ COUNTIF(is_ticket_unread = TRUE) AS unread_open_tickets,
+ SAFE_DIVIDE(COUNTIF(is_ticket_unread = TRUE), NULLIF(COUNT(DISTINCT sm_ticket_key), 0)) AS unread_open_ticket_rate
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND ticket_status IS NOT NULL
+ AND LOWER(ticket_status) = 'open'
+ GROUP BY 1, 2
+ HAVING COUNT(DISTINCT sm_ticket_key) >= 25
+ ORDER BY unread_open_ticket_rate DESC, open_tickets DESC;
+ ```
+
+
+
+ **What you'll learn:** Which tagged issue types generate the most tickets, and whether they tend to be one-touch or slow to resolve. Useful for product feedback loops, macro coverage, and staffing.
+
+ ```sql
+ -- Assumptions: timeframe=last_90_days | metric=ticket_volume+one_touch_rate+resolution_time | grain=tag | scope=exclude_spam
+ WITH base AS (
+ SELECT
+ sm_ticket_key,
+ ticket_status,
+ is_ticket_one_touch,
+ ticket_resolution_time_hours,
+ ticket_tag_names_csv
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND ticket_created_at_local_datetime IS NOT NULL
+ AND DATE(ticket_created_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
+ AND ticket_tag_names_csv IS NOT NULL
+ AND TRIM(ticket_tag_names_csv) != ''
+ ),
+ exploded AS (
+ SELECT DISTINCT
+ sm_ticket_key,
+ ticket_status,
+ is_ticket_one_touch,
+ ticket_resolution_time_hours,
+ LOWER(TRIM(tag_raw)) AS tag
+ FROM base
+ CROSS JOIN UNNEST(SPLIT(ticket_tag_names_csv, ',')) AS tag_raw
+ WHERE TRIM(tag_raw) != ''
+ )
+ SELECT
+ tag,
+ COUNT(DISTINCT sm_ticket_key) AS tickets,
+ COUNTIF(is_ticket_one_touch = TRUE) AS one_touch_tickets,
+ SAFE_DIVIDE(COUNTIF(is_ticket_one_touch = TRUE), NULLIF(COUNT(DISTINCT sm_ticket_key), 0)) AS one_touch_rate,
+ COUNTIF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'closed') AS closed_tickets,
+ AVG(IF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'closed', ticket_resolution_time_hours, NULL)) AS avg_resolution_time_hours_closed
+ FROM exploded
+ GROUP BY 1
+ HAVING tickets >= 50
+ ORDER BY tickets DESC
+ LIMIT 50;
+ ```
+
+
+ One ticket can have multiple tags, so a single ticket may appear in multiple tag rows. Use this for per-tag diagnostics, not for global totals.
+
+
+
+
+ **What you'll learn:** Which priority/channel/team combinations generate the most tickets, and whether they are being resolved quickly. Useful for triage rules and staffing.
+
+ ```sql
+ -- Assumptions: timeframe=last_30_days | metric=ticket_volume+resolution_time | grain=priority+channel+team | scope=exclude_spam
+ SELECT
+ COALESCE(NULLIF(LOWER(TRIM(ticket_priority)), ''), '(unknown)') AS ticket_priority,
+ COALESCE(NULLIF(LOWER(TRIM(ticket_communication_channel)), ''), '(unknown)') AS ticket_communication_channel,
+ COALESCE(NULLIF(TRIM(ticket_assignee_team_name), ''), '(unassigned)') AS ticket_assignee_team_name,
+ COUNT(DISTINCT sm_ticket_key) AS tickets,
+ COUNTIF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'open') AS open_tickets,
+ COUNTIF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'closed') AS closed_tickets,
+ COUNTIF(is_ticket_one_touch = TRUE) AS one_touch_tickets,
+ SAFE_DIVIDE(COUNTIF(is_ticket_one_touch = TRUE), NULLIF(COUNT(DISTINCT sm_ticket_key), 0)) AS one_touch_rate,
+ AVG(IF(ticket_status IS NOT NULL AND LOWER(ticket_status) = 'closed', ticket_resolution_time_hours, NULL)) AS avg_resolution_time_hours_closed
+ FROM `your_project.sm_transformed_v2.obt_customer_support_tickets`
+ WHERE is_ticket_spam = FALSE
+ AND ticket_created_at_local_datetime IS NOT NULL
+ AND DATE(ticket_created_at_local_datetime) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ GROUP BY 1, 2, 3
+ HAVING tickets >= 25
+ ORDER BY tickets DESC;
+ ```
+
+
+
+---
+
+## Request a Query
+
+Have a question that's not covered here? We regularly add new queries. If there's a template you'd like added (subscription churn, cohort LTV curves, creative performance, etc.), reach out to your SourceMedium team and include the business question and the table(s) you're using.
diff --git a/data-inputs/attribution-health/index.mdx b/data-inputs/attribution-health/index.mdx
new file mode 100644
index 0000000..2bed55c
--- /dev/null
+++ b/data-inputs/attribution-health/index.mdx
@@ -0,0 +1,114 @@
+---
+title: 'Attribution Health'
+sidebarTitle: 'Overview'
+description: 'Strategies and tools for improving your attribution coverage and data quality'
+icon: 'heart-pulse'
+---
+
+## What is Attribution Health?
+
+Attribution health measures how completely your marketing touchpoints are being captured and connected to customer purchases. High attribution rates mean you can confidently analyze which channels drive revenue; low rates mean you're flying blind.
+
+
+If you're seeing high rates of `(direct) / (none)` in your attribution data, this section will help you diagnose and fix the gaps.
+
+
+---
+
+## Common Attribution Gaps
+
+
+
+ Ad blockers, iOS privacy features, and browser restrictions prevent traditional tracking from capturing touchpoints.
+
+
+ Customers moving between domains (ads → landing page → checkout) can lose UTM parameters along the way.
+
+
+ Marketing campaigns without proper UTM tagging result in traffic appearing as direct/none.
+
+
+ Long consideration cycles mean the original touchpoint expires before purchase.
+
+
+
+---
+
+## Attribution Health Toolkit
+
+The following guides cover different strategies for improving your attribution coverage. Most brands benefit from implementing multiple approaches.
+
+### First-Party Attributes & Tracking
+
+
+
+ **Shopify Plus** — Capture UTM parameters at checkout using Checkout UI Extensions, bypassing cookie blockers.
+
+
+ **All Platforms** — Standardize UTM tagging so last-click attribution stays consistent.
+
+
+ **All Platforms** — Best practices for UTM naming conventions and tracking hygiene.
+
+
+ Learn what `(direct) / (none)` means and how to reduce it.
+
+
+
+### Zero-Party Data Methods
+
+
+
+ Learn how self-reported survey answers complement tracking-based attribution.
+
+
+ **All Platforms** — Ask customers directly how they heard about you. Complements tracking-based attribution.
+
+
+ Set up Fairing for automated post-purchase surveys with order tagging.
+
+
+ Set up KnoCommerce for zero-party data collection and attribution.
+
+
+
+---
+
+## Choosing the Right Approach
+
+| Method | Best For | Limitations |
+|--------|----------|-------------|
+| **Checkout Attributes** | High ad blocker rates, Shopify Plus stores | Doesn't work with accelerated checkout (Apple Pay, etc.) |
+| **HDYHAU Surveys** | Understanding top-of-funnel discovery | Self-reported data can be inaccurate |
+| **UTM Best Practices** | Prevention—catching gaps before they happen | Doesn't fix historical data |
+| **Fairing/KnoCommerce** | Automated survey collection at scale | Requires additional integration |
+
+
+**Recommended approach**: Implement UTM best practices as your foundation, add checkout attribute capture for robust input, and use HDYHAU surveys to validate and supplement your tracking-based data.
+
+
+---
+
+## Measuring Your Attribution Health
+
+SourceMedium's MTA dashboard includes an **Attribution Health** module that shows:
+- Percentage of orders with attributable touchpoints
+- Attribution rates by channel and time period
+- Trends in your attribution coverage
+
+
+ Learn how to interpret your attribution health metrics in the MTA dashboard.
+
+
+---
+
+## Related Resources
+
+
+
+ How SourceMedium prioritizes attribution data from multiple sources.
+
+
+ Organize your attributed orders into meaningful channel groupings.
+
+
diff --git a/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard.mdx b/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard.mdx
index 94493f2..44508e4 100644
--- a/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard.mdx
@@ -1,11 +1,12 @@
---
title: "Can I set targets in my dashboard?"
+description: "How to configure metric targets in the configuration sheet and surface target widgets in Executive Summary."
sidebarTitle: "Setting Metric Targets"
icon: 'question-mark'
---
### Requirements
-All post-trial plans support target setting.
+Target setting is available as part of the SourceMedium feature set.
### Background
@@ -26,18 +27,21 @@ Please reach out to the SourceMedium Customer Solutions Analyst team to enable t
### Steps
-1. Open your SourceMedium Configuration Sheet at the link pinned in your SourceMedium shared slack Channel.
+1. Open your SourceMedium Configuration Sheet:
+ - Check your onboarding email thread for the Google Sheets link
+ - Check your shared SourceMedium Slack channel for the Configuration Sheet link (often pinned)
+ - If you can’t find it, email [support@sourcemedium.com](mailto:support@sourcemedium.com)

2. Open the `Targets` tab
3. Select a channel. This will be the sales channel that you are looking to track metrics for, i.e. `Online DTC` (Online DTC is the only option available at the moment for Target Setting as the feature is further developed).
4. Add a `date_start` in order to indicate when the goal is being tracked starts (We encourage MTD tracking).
-5. Add a `date_end`, this sets the period of time that you want the target amortized across. If left blank it will all be set for the `date_start` day.
-
- *(i.e. You set \$1m revenue for 11/1 but don't set the end date your target will be $1m for the single day, not spread across the month).*
+5. Add a `date_end`, this sets the period of time that you want the target applied across. If left blank it will all be set for the `date_start` day.
+ - Targets are applied as **daily values** across the range from `date_start` to `date_end` (inclusive).
+ - If you want a monthly total target, enter the **per-day** target value for the month and set `date_end` to the last day of the period.
6. Add target values to the metrics you'd like to track.

-7. Reach out to the SourceMedium team in your slack channel or at [support@sourcemedium.com](mailto:support@supportmedium.com) to get the target widgets added to your dashboard!
\ No newline at end of file
+7. Reach out to the SourceMedium team in your Slack channel or at [support@sourcemedium.com](mailto:support@sourcemedium.com) to get the target widgets added to your dashboard!
diff --git a/data-inputs/configuration-sheet/config-sheet-overview.mdx b/data-inputs/configuration-sheet/config-sheet-overview.mdx
index 8c38349..dacafdb 100644
--- a/data-inputs/configuration-sheet/config-sheet-overview.mdx
+++ b/data-inputs/configuration-sheet/config-sheet-overview.mdx
@@ -1,23 +1,101 @@
---
title: "Configuration Sheet Overview"
+sidebarTitle: "Overview"
+description: "How to use the SourceMedium Configuration Sheet to enrich your data with targets, channel mapping, costs, and custom metrics"
+icon: "table"
---
-The SourceMedium Configuration Sheet is a a powerful tool that allows you to enrich your own data based on your business's specific needs.
+The SourceMedium Configuration Sheet is a powerful Google Sheets-based tool that allows you to enrich your data based on your business's specific needs—without writing any code.
-The standard SourceMediun Configuration sheet gives your team the ability to:
-- [Set targets for executive-level metrics](/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard)
-- [Map orders to specific channels, sub-channels, and vendors for easier analysis](/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels)
-- Surface non-integrated [marketing costs](/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet) and [sales](/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab) into your dashboard
-- Enable **Profit & Loss** analysis by entering COGS other costs related to your business...
+
+Your Configuration Sheet is automatically synced to SourceMedium. Changes typically reflect in your dashboard within 24 hours.
+
+---
+
+## What Can You Configure?
+
+
+
+ Set targets for executive-level metrics like revenue, orders, and ROAS.
+
+
+ Map orders to specific channels, sub-channels, and vendors for easier analysis.
+
+
+ Add marketing spend from non-integrated platforms (influencers, podcasts, etc.).
+
+
+ Enter sales from non-integrated channels (retail, wholesale, marketplaces).
+
+
+ Exact tab/column schema for ingestion (Targets, Channel Mapping, Costs, Sales).
+
+
+
+---
+
+## Cost of Goods Sold (COGS)
+
+Enable Profit & Loss analysis by adding your cost data. When COGS is enabled, additional tabs appear in your Configuration Sheet:
+
+
+
+ Enter product-level costs. SourceMedium automatically syncs Shopify product costs.
+
+
+ Add shipping and delivery costs.
+
+
+ Track fulfillment and 3PL fees.
+
+
+ Include payment processing fees (Stripe, PayPal, etc.).
+
+
+ Add fixed operating costs for full P&L visibility.
+
+
+
+---
-If you choose to enable **Costs of Goods Sold (COGS)** within SourceMedium, new tabs are added to your Configuration sheet that allow you to enter:
+## How to Access Your Configuration Sheet
+
+Your Configuration Sheet is shared with you during onboarding.
+
+1. Check your onboarding email thread for the Google Sheets link
+2. Check your shared SourceMedium Slack channel for the Configuration Sheet link (often pinned)
+3. If you can’t find it, email [support@sourcemedium.com](mailto:support@sourcemedium.com) and we’ll resend access
+
+
+Bookmark your Configuration Sheet for quick access. You can also request view/edit access for team members.
+
+
+---
+
+## Best Practices
+
+
+
+ Use the same naming conventions across tabs. For example, if you call a channel "Meta" in one place, don't call it "Facebook" elsewhere.
+
+
+ Product costs and shipping rates change. Set a recurring reminder to review and update your cost data quarterly.
+
+
+ Add notes in the sheet explaining why certain orders are mapped to specific channels—future you will thank you.
+
+
+
+---
-- [Product Costs](/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs-from-platforms-outside-of-shopify-into-my-dashboard) (for non-Shopify, or historic backfill of Shopify product costs)
- - SourceMedium automatically syncs the latest Product Cost values entered in your Shopify account
-- [Shipping Costs](/data-inputs/configuration-sheet/costs/how-do-i-surface-shipping-costs-within-my-dashboard)
-- [Fulfillment Costs](/data-inputs/configuration-sheet/costs/how-do-i-surface-fulfillment-costs-within-my-dashboard)
-- [Merchant Processing Fees](/data-inputs/configuration-sheet/costs/how-do-i-surface-merchant-processing-fees-within-my-dashboard)
-- [Operating Expenses](/data-inputs/configuration-sheet/costs/how-do-i-surface-operating-expenses-within-my-dashboard)
+## Related Resources
-[def]: data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels
\ No newline at end of file
+
+
+ Learn how channel mapping logic works.
+
+
+ Track influencer spend and performance with UTM codes.
+
+
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-add-historic-product-costs-from-shopify-into-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-add-historic-product-costs-from-shopify-into-my-dashboard.mdx
index c1e229f..09ebf17 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-add-historic-product-costs-from-shopify-into-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-add-historic-product-costs-from-shopify-into-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I add historic Product Costs from Shopify into my dashboard"
+description: "How to backfill historic Shopify product costs (COGS) so gross profit and LTV metrics reflect accurate margins."
sidebarTitle: "Adding Historic Product Costs"
icon: 'question-mark'
---
@@ -19,7 +20,7 @@ Keeping track of `product costs` is crucial for your business. It is a significa
- Go to the **Financial Cost - Product COGS** Tab
- Enter the below:
- category = Financial
- - channel = Online DTC
+ - sm_channel Online DTC
- expense_channel = Product COGS
- SKU
- product cost - *This is your cost per product*
@@ -57,4 +58,4 @@ Tables where these costs are currently available:
- What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-override-product-costs-from-shopify-into-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-override-product-costs-from-shopify-into-my-dashboard.mdx
index 7957351..a405149 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-override-product-costs-from-shopify-into-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-override-product-costs-from-shopify-into-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I override Product Costs from Shopify into my dashboard?"
+description: "How to override Shopify product costs (COGS) via the configuration sheet so reporting uses your preferred cost basis."
sidebarTitle: "Overriding Product Costs"
icon: 'question-mark'
---
@@ -17,7 +18,7 @@ Keeping track of `product costs` is crucial for your business. It is a significa
1. Go to the **Financial Cost - Product COGS** Tab
2. Enter the below:
- category = Financial
- - channel = Online DTC
+ - sm_channel Online DTC
- expense_channel = Product COGS
- SKU
- product cost - *This is your cost per product*
@@ -56,4 +57,4 @@ Called `Product Gross Profit`
#### What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-fulfillment-costs-within-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-fulfillment-costs-within-my-dashboard.mdx
index 3c6c87d..a9e9f38 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-fulfillment-costs-within-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-fulfillment-costs-within-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Fulfillment Costs within my dashboard?"
+description: "How to add fulfillment/3PL costs via the configuration sheet so they’re included in gross profit reporting."
sidebarTitle: "Surfacing Fullfillment Costs"
icon: 'question-mark'
---
@@ -57,4 +58,4 @@ Tracking `fulfillment costs` is crucial for your business. It is a significant e
#### What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-merchant-processing-fees-within-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-merchant-processing-fees-within-my-dashboard.mdx
index a1766c7..0330705 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-merchant-processing-fees-within-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-merchant-processing-fees-within-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Merchant Processing Fees within my dashboard?"
+description: "How to add merchant processing fees via the configuration sheet so they’re allocated into profit and order reporting."
sidebarTitle: "Surfacing Merchant Processing Fees"
icon: 'question-mark'
---
@@ -66,4 +67,4 @@ It is imperative to make sure you include a date_end date as the order/row will
#### What of my vendor is not available as part of the preselected dropdown?
-If you do not see your vendor listed in the preselected dropdown, reach out to the CSA Team and they will be able to get your vendor added to the dropdown.
\ No newline at end of file
+If you do not see your vendor listed in the preselected dropdown, reach out to the CSA Team and they will be able to get your vendor added to the dropdown.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-operating-expenses-within-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-operating-expenses-within-my-dashboard.mdx
index 537febc..2997da5 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-operating-expenses-within-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-operating-expenses-within-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Operating Expenses within my dashboard?"
+description: "How to add operating expenses in the configuration sheet so they appear in executive reporting."
sidebarTitle: "Surfacing Operating Expenses"
icon: 'question-mark'
---
@@ -44,4 +45,4 @@ Keeping track of `Operating Expenses` is crucial for your business. It is a sign
### FAQs:
#### What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs-from-platforms-outside-of-shopify-into-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs-from-platforms-outside-of-shopify-into-my-dashboard.mdx
index 945c348..829f5eb 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs-from-platforms-outside-of-shopify-into-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs-from-platforms-outside-of-shopify-into-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Product Costs from Platforms outside of Shopify into my dashboard?"
+description: "How to add non-Shopify product costs (COGS) for channels like Amazon/Retail/Wholesale via the configuration sheet."
sidebarTitle: "Surfacing Non-Shopify Product Costs"
icon: 'question-mark'
---
@@ -18,7 +19,7 @@ Keeping track of `product costs` is crucial for your business. It is a significa
2. Enter the below:
- category = Financial
- channel (Amazon, Retail, Wholesale, etc)
- 1. If you have already imputed your Product Costs in Shopify, then you do not need to enter any costs for your Online DTC channel unless you want to enter historical Shopify Product costs (See how to do that [HERE](https://www.notion.so/How-do-I-add-historical-Product-Costs-from-Shopify-into-my-dashboard-42737f70658f41308f57253d779b2d53?pvs=21)).
+ 1. If you have already imputed your Product Costs in Shopify, then you do not need to enter any costs for your Online DTC channel unless you want to enter historical Shopify Product costs (See how to do that [here](/data-inputs/configuration-sheet/costs/how-do-i-add-historic-product-costs-from-shopify-into-my-dashboard)).
2. Amazon SKUs and Shopify SKUs can be the same but they are usually different. Please add any Amazon SKUs, whether it is the same or different to the config sheet and set the channel to Amazon.
- expense_channel = Product COGS
- product cost - *This is your cost per product*
@@ -58,4 +59,4 @@ Keeping track of `product costs` is crucial for your business. It is a significa
### What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs.mdx
index 4fac807..59118c1 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Product Costs/COGS within my dashboard?"
+description: "How to surface Shopify product costs (COGS) so product gross profit and related metrics are available in dashboards."
sidebarTitle: "How to surface Shopify Product Costs"
icon: 'question-mark'
---
diff --git a/data-inputs/configuration-sheet/costs/how-do-i-surface-shipping-costs-within-my-dashboard.mdx b/data-inputs/configuration-sheet/costs/how-do-i-surface-shipping-costs-within-my-dashboard.mdx
index f95c6cf..1468796 100644
--- a/data-inputs/configuration-sheet/costs/how-do-i-surface-shipping-costs-within-my-dashboard.mdx
+++ b/data-inputs/configuration-sheet/costs/how-do-i-surface-shipping-costs-within-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "How do I surface Shipping Costs within my dashboard?"
+description: "How to add shipping costs via the configuration sheet so they’re reflected in executive and LTV/profit metrics."
sidebarTitle: "Surfacing Shipping Costs"
icon: 'question-mark'
---
@@ -54,4 +55,4 @@ Keeping track of `shipping costs` is crucial for your business. It is a signific
#### What happens if no date_end date is provided?
- It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
\ No newline at end of file
+ It is imperative to make sure you include a date_end date as the order/row will not be included if it does not have a date_end date.
diff --git a/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels.mdx b/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels.mdx
index db275e3..a50ade7 100644
--- a/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels.mdx
+++ b/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels.mdx
@@ -1,11 +1,12 @@
---
title: "How can I create order channels and sub-channels?"
+description: "How to create channel mapping rules in the configuration sheet to group orders into channels and sub-channels."
sidebarTitle: "Creating order Channels & Sub-Channels"
icon: 'question-mark'
---
### Requirements
-All plans (including trial) support channel mapping.
+Channel mapping is available as part of the SourceMedium feature set.
### Background
@@ -37,6 +38,6 @@ SourceMedium has a unique feature called **channel mapping** which uses your **S

-6. After the configuration sheet is integrated into your dashboard (happens hourly), your **sub-channels** will available for filtering in your dashboard.
+6. After the configuration sheet is integrated into your dashboard, your **sub-channels** will be available for filtering in your dashboard. Changes typically reflect within 24 hours.
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/configuration-sheet/how-can-i-track-influencer-spend-and-performance.mdx b/data-inputs/configuration-sheet/how-can-i-track-influencer-spend-and-performance.mdx
index 27f8092..0f87b7c 100644
--- a/data-inputs/configuration-sheet/how-can-i-track-influencer-spend-and-performance.mdx
+++ b/data-inputs/configuration-sheet/how-can-i-track-influencer-spend-and-performance.mdx
@@ -1,5 +1,6 @@
---
title: "How can I track influencer spend and performance?"
+description: "How to track influencer spend and performance using discount codes and the configuration sheet Cost tab."
sidebarTitle: "Tracking Influencer Spend & Performance"
icon: 'question-mark'
---
@@ -8,7 +9,7 @@ icon: 'question-mark'
Access to Configuration sheet to input custom marketing spend
**If this is your first time using the Cost tab:**
- - Once all steps have been completed, reach out to the Source Medium team in Slack (or [via email](mailto:support@sourcemedium.com)) letting us know you'd like to enable the custom costs feature
+ - Once all steps have been completed, reach out to the SourceMedium team in Slack (or [via email](mailto:support@sourcemedium.com)) letting us know you'd like to enable the custom costs feature
### Background
@@ -20,8 +21,10 @@ To get influencer data populated in the Sponsorships & Influencers page of your
### Steps
-1. Open your configuration sheet (find the link in `pinned messages` in your Slack channel)
- *Note: If you cannot find this link or do not utilize Slack, email our team for access to your configuration sheet.*
+1. Open your Configuration Sheet:
+ - Check your onboarding email thread for the Google Sheets link
+ - Check your shared SourceMedium Slack channel for the Configuration Sheet link (often pinned)
+ - If you can’t find it, email [support@sourcemedium.com](mailto:support@sourcemedium.com)

@@ -35,6 +38,6 @@ To get influencer data populated in the Sponsorships & Influencers page of your
**If this is your first time using the Cost tab:**
- - Once all steps have been completed, reach out to the Source Medium team in Slack (or via email) letting us know you'd like to enable Influencer Tracking feature.
+ - Once all steps have been completed, reach out to the SourceMedium team in Slack (or via email) letting us know you'd like to enable Influencer Tracking feature.
-You will soon see your newly entered spend accounted for (for the designated dates) in your **Executive Summary's** spend metric, on the Marketing Performance dash, and you will see performance surfaced to your **Sponsorships & Influencers** page -- spend along with order counts, revenue, AOV, ROAS etc.
\ No newline at end of file
+You will soon see your newly entered spend accounted for (for the designated dates) in your **Executive Summary's** spend metric, on the Marketing Performance dash, and you will see performance surfaced to your **Sponsorships & Influencers** page -- spend along with order counts, revenue, AOV, ROAS etc.
diff --git a/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab.mdx b/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab.mdx
index 5359d57..40fc2ca 100644
--- a/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab.mdx
+++ b/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab.mdx
@@ -1,6 +1,7 @@
---
title: "How do I enter non-integrated sales data through my Configuration Sheet (Sales tab)?"
-sidebarTitle: "Entering non-intergrated sales data"
+description: "How to add sales from non-integrated platforms (retail/wholesale/etc.) using the configuration sheet Sales tab."
+sidebarTitle: "Entering non-integrated sales data"
icon: 'question-mark'
---
### Background
@@ -33,6 +34,6 @@ Even if SourceMedium doesn't currently support one of your sales platforms — e
- These are currently the only metrics supported by the Sales tab
- Reach out to the SM team if you have a need that isn't covered by these metric options, we'll do our best to come up with an alternate solution, or we'll add it to our R&D queue
4. Enter data into the sheet using the the schema explained above.
-5. If you're using the Sales Tab for the very first time, you'll just need to reach out to the SM team to enable the feature. After the feature has been enabled by the SM team, data and updates will be picked up and routed to your report automatically every hour
+5. If you're using the Sales tab for the very first time, you'll just need to reach out to the SourceMedium team to enable the feature. After it’s enabled, updates will be picked up and routed to your report automatically after the next Configuration Sheet sync.
----
\ No newline at end of file
+---
diff --git a/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet.mdx b/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet.mdx
index bff4a0c..c811a98 100644
--- a/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet.mdx
+++ b/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet.mdx
@@ -1,5 +1,6 @@
---
title: "How do I include marketing spend through the cost tab of the configuration sheet?"
+description: "How to add non-integrated marketing spend via the configuration sheet Cost tab so it appears in executive and marketing reporting."
sidebarTitle: "Adding Marketing Spend Using the Cost Tab"
icon: 'question-mark'
---
@@ -19,8 +20,10 @@ You can use the cost tab in your configuration sheet to include any `marketing s
### **Steps**
-1. Open your configuration sheet (find the link in `pinned messages` in your Slack channel)
- 1. If not in Slack, email our team for access to your configuration sheet
+1. Open your Configuration Sheet:
+ - Check your onboarding email thread for the Google Sheets link
+ - Check your shared SourceMedium Slack channel for the Configuration Sheet link (often pinned)
+ - If you can’t find it, email [support@sourcemedium.com](mailto:support@sourcemedium.com)

@@ -29,7 +32,7 @@ You can use the cost tab in your configuration sheet to include any `marketing s
2. In the `Cost` tab, select the appropriate values for each column
1. `category` - select `Marketing`
2. `channel` - select the channel where you're expecting to see returns on this spend (Online DTC, Wholesale, etc.)
- 3. `sub-channel` - select the sub-channel that the spend is associated with ([new sub-channels can also be added](https://help.sourcemedium.com/articles/channel-mapping-using-your-source-medium-configurations-sheet) within the `Configuration` tab)
+ 3. `sub-channel` - select the sub-channel that the spend is associated with ([new sub-channels can also be added](/data-inputs/configuration-sheet/how_does_channel_mapping_work) within the `Configuration` tab)
**Any `sub_channel`containing the following terms (not case sensitive) will be pulled into the `Sponsorships & Influencers` module:**
- `influencer`
@@ -47,4 +50,4 @@ You can use the cost tab in your configuration sheet to include any `marketing s
### **Additional information and related articles**
-- ****[Creating sub-channels of orders by channel mapping in the configuration sheet](data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels)****
\ No newline at end of file
+- [Creating order channels and sub-channels (Channel Mapping)](/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels)
diff --git a/data-inputs/configuration-sheet/how_does_channel_mapping_work.mdx b/data-inputs/configuration-sheet/how_does_channel_mapping_work.mdx
index bd65086..7ff8a14 100644
--- a/data-inputs/configuration-sheet/how_does_channel_mapping_work.mdx
+++ b/data-inputs/configuration-sheet/how_does_channel_mapping_work.mdx
@@ -1,9 +1,9 @@
---
title: "How does channel mapping work in the SourceMedium Dashboard?"
+description: "How SourceMedium assigns orders and spend to channels, including the precedence rules and default logic."
sidebarTitle: "How does channel mapping work?"
icon: 'question-mark'
---
-
## Overview
Channel mapping is a core feature that helps categorize orders and marketing spend into specific channels for better analysis and reporting. This documentation explains how orders are mapped to channels and how you can customize this mapping for your brand.
@@ -221,4 +221,15 @@ The system also tracks specific sales platforms and integrations, including:
- Channel mapping affects both order attribution and marketing spend attribution.
- Automated tagging through Shopify Flow helps maintain data consistency.
-> For specific questions about your brand's channel mapping configuration or help setting up Shopify Flow automations, please reach out to your SourceMedium representative.
\ No newline at end of file
+> For specific questions about your brand's channel mapping configuration or help setting up Shopify Flow automations, please reach out to your SourceMedium representative.
+
+## Related Resources
+
+
+
+ Technical documentation on how sm_channel is determined
+
+
+ Learn about all order segmentation dimensions
+
+
diff --git a/data-inputs/data-inputs-overview.mdx b/data-inputs/data-inputs-overview.mdx
index b4910e9..596dda7 100644
--- a/data-inputs/data-inputs-overview.mdx
+++ b/data-inputs/data-inputs-overview.mdx
@@ -1,7 +1,29 @@
---
-title: 'Data Integrations & Inputs'
-description: ''
-icon: 'plug'
+title: "Data integrations & inputs"
+description: "Overview of how SourceMedium ingests data, supported integration types, and what to do when an integration isn’t available"
+icon: "plug"
---
-blah blah blah
\ No newline at end of file
+This section covers how SourceMedium ingests data from your sales, marketing, subscription, and analytics platforms, plus what you can provide via user inputs.
+
+## What counts as an “integration”
+
+Integrations fall into a few buckets:
+
+- **Direct platform integrations** (Shopify, GA4, ad platforms, etc.)
+- **Connectors / ingestion partners** (where applicable)
+- **User inputs** via the SourceMedium Configuration Sheet (costs, targets, and non-integrated sales)
+
+## Getting started
+
+1. Start with the full list of supported integrations: [All available integrations](/data-inputs/platform-integration-instructions/all-available-integrations)
+2. Connect your highest-impact sources first:
+ - Ecommerce sales (Shopify / Amazon)
+ - Paid media (Google Ads / Meta Ads / Amazon Ads)
+ - Web analytics (GA4)
+3. Standardize channels and fill gaps using the configuration sheet:
+ - [Configuration sheet overview](/data-inputs/configuration-sheet/config-sheet-overview)
+
+## Common questions
+
+- “Why don’t external reports match SourceMedium?” Start here: [Why would external reports not match the SourceMedium dashboard?](/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard)
diff --git a/data-inputs/platform-integration-instructions/all-available-integrations.mdx b/data-inputs/platform-integration-instructions/all-available-integrations.mdx
index acd3446..9161ce7 100644
--- a/data-inputs/platform-integration-instructions/all-available-integrations.mdx
+++ b/data-inputs/platform-integration-instructions/all-available-integrations.mdx
@@ -632,19 +632,6 @@ icon: 'plug'
}/>
-
-
-
-
-
-
-
-
-
-
-}/>
-
@@ -664,14 +651,6 @@ icon: 'plug'
}/>
-
-
-
-
-
-}/>
-
diff --git a/data-inputs/platform-integration-instructions/amazon-ads-integration.mdx b/data-inputs/platform-integration-instructions/amazon-ads-integration.mdx
index ef80724..63ad859 100644
--- a/data-inputs/platform-integration-instructions/amazon-ads-integration.mdx
+++ b/data-inputs/platform-integration-instructions/amazon-ads-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Amazon Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Amazon Ads data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Amazon Ads data to SourceMedium dashboards.
### Requirements
@@ -23,4 +22,4 @@ icon: 'plug'
1. If you see issues with SourceMedium displaying an advertiser profile you think is attached to a specific account, check your **Seller Central** account **Campaign Manager** permissions in addition to the **Advertising console**. Selecting the permissions within the Advertising console will automatically set them in Seller Central
2. Sometimes, permissions do not sync ****between **Amazon Ads** and **Seller Central**. Often, it’s because someone accidentally removes this permission. Check Seller Central permissions to make sure the **Campaign Manager** permissions are set as you see here:
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-integration-instructions/amazon-dsp-integration.mdx b/data-inputs/platform-integration-instructions/amazon-dsp-integration.mdx
index 3057ec0..bf7e029 100644
--- a/data-inputs/platform-integration-instructions/amazon-dsp-integration.mdx
+++ b/data-inputs/platform-integration-instructions/amazon-dsp-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Amazon DSP - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Amazon DSP data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Amazon DSP data to SourceMedium.
### Requirements
@@ -36,4 +35,4 @@ Then, click **Save**:
1. Once we are invited as a user with the correct permissions, we will be able to integrate your data into your dashboard!
----
\ No newline at end of file
+---
diff --git a/data-inputs/platform-integration-instructions/amazon-sc-integration.mdx b/data-inputs/platform-integration-instructions/amazon-sc-integration.mdx
index 295c6a0..49c825b 100644
--- a/data-inputs/platform-integration-instructions/amazon-sc-integration.mdx
+++ b/data-inputs/platform-integration-instructions/amazon-sc-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Amazon Seller Central - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Amazon Seller Central data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Amazon Seller Central (Selling Partner) data to SourceMedium.
### Requirements
@@ -53,5 +52,5 @@ Add SourceMedium as a user in Seller Central
---
-> [FAQ article on the new Amazon SP-API integration](https://help.sourcemedium.com/articles/what-are-the-implications-of-the-new-beta-amazon-sp-api-integration)
->
\ No newline at end of file
+> [FAQ article on the new Amazon SP-API integration](/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration)
+>
diff --git a/data-inputs/platform-integration-instructions/amazon-vc-integration.mdx b/data-inputs/platform-integration-instructions/amazon-vc-integration.mdx
index 2116772..d216223 100644
--- a/data-inputs/platform-integration-instructions/amazon-vc-integration.mdx
+++ b/data-inputs/platform-integration-instructions/amazon-vc-integration.mdx
@@ -1,10 +1,9 @@
---
title: '[Beta] Amazon Vendor Central - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your [Beta] Amazon Vendor Central data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Amazon Vendor Central data to SourceMedium.
### Requirements
@@ -45,5 +44,5 @@ Add SourceMedium as a user in Vendor Central
---
-> [FAQ article on the new Amazon SP-API integration](https://help.sourcemedium.com/articles/what-are-the-implications-of-the-new-beta-amazon-sp-api-integration)
->
\ No newline at end of file
+> [FAQ article on the new Amazon SP-API integration](/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration)
+>
diff --git a/data-inputs/platform-integration-instructions/applovin-integration.mdx b/data-inputs/platform-integration-instructions/applovin-integration.mdx
index e8d883a..1c4ae87 100644
--- a/data-inputs/platform-integration-instructions/applovin-integration.mdx
+++ b/data-inputs/platform-integration-instructions/applovin-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'AppLovin - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your AppLovin data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your AppLovin data to your SourceMedium dashboard.
### Requirements
@@ -15,14 +14,14 @@ icon: 'plug'
1. Log in to your AppLovin dashboard using your master user account (not a sub-user account).
-2. Navigate to the Account tab in the left side panel.
- 
+2. Navigate to the top of the page and open the Account tab.
+ 
3. Within the Account tab select the "Keys" option.
- 
+ 
-4. Copy your Report Key.
- 
+4. Copy your Reporting Key.
+ 
5. Email the Report Key to us at **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)**
diff --git a/data-inputs/platform-integration-instructions/autopilot-integration.mdx b/data-inputs/platform-integration-instructions/autopilot-integration.mdx
index a4872db..c87e549 100644
--- a/data-inputs/platform-integration-instructions/autopilot-integration.mdx
+++ b/data-inputs/platform-integration-instructions/autopilot-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Autopilot - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Autopilot data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Autopilot data to SourceMedium.
### Requirements
@@ -18,4 +17,4 @@ icon: 'plug'
3. In the Setting menu, click **Autopilot API**
1. If you haven’t used the API before, you’ll need to generate a new key. Click the **Generate** button
2. Your API Key will display
-4. Email the API key to **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)**
\ No newline at end of file
+4. Email the API key to **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)**
diff --git a/data-inputs/platform-integration-instructions/awin-integration.mdx b/data-inputs/platform-integration-instructions/awin-integration.mdx
index 8810166..3131526 100644
--- a/data-inputs/platform-integration-instructions/awin-integration.mdx
+++ b/data-inputs/platform-integration-instructions/awin-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Awin - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Awin data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Awin data to SourceMedium.
### Requirements
@@ -27,4 +26,4 @@ icon: 'plug'
### Additional information
-- Your OAuth 2 access token is linked to your personal user account, it is not linked to a certain publisher or advertiser account. If you have access to 10 different Awin publisher accounts via the website, then your personal API token grants you access to data from all of those 10 accounts. If you add or remove your user account to or from a publisher or advertiser account, it may take up to 10 minutes until this change in access rights takes effect in the API. If someone unauthorized gets access to your token, you can revoke it on the same page. This also requires your password and shows a popup warning to ask you if you’re sure.
\ No newline at end of file
+- Your OAuth 2 access token is linked to your personal user account, it is not linked to a certain publisher or advertiser account. If you have access to 10 different Awin publisher accounts via the website, then your personal API token grants you access to data from all of those 10 accounts. If you add or remove your user account to or from a publisher or advertiser account, it may take up to 10 minutes until this change in access rights takes effect in the API. If someone unauthorized gets access to your token, you can revoke it on the same page. This also requires your password and shows a popup warning to ask you if you’re sure.
diff --git a/data-inputs/platform-integration-instructions/bing-integration.mdx b/data-inputs/platform-integration-instructions/bing-integration.mdx
index c4a81ef..867bf02 100644
--- a/data-inputs/platform-integration-instructions/bing-integration.mdx
+++ b/data-inputs/platform-integration-instructions/bing-integration.mdx
@@ -1,6 +1,7 @@
---
title: 'Bing Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
+description: 'Connect your Microsoft Bing Ads account to SourceMedium for unified ad performance reporting'
icon: 'plug'
---
@@ -32,4 +33,4 @@ Alternatively, you can find the approval link in your account from the top navig

-
\ No newline at end of file
+
diff --git a/data-inputs/platform-integration-instructions/blotout-integration.mdx b/data-inputs/platform-integration-instructions/blotout-integration.mdx
index 7e6dc2e..e0a0ccb 100644
--- a/data-inputs/platform-integration-instructions/blotout-integration.mdx
+++ b/data-inputs/platform-integration-instructions/blotout-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Blotout - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Blotout data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Blotout data to SourceMedium.
### Requirements
@@ -12,4 +11,4 @@ icon: 'plug'
### Background
-SourceMedium will be able to connect your Blotout event-based tracking to our transactional level data from your eCommerce store for near live-time reporting!
\ No newline at end of file
+SourceMedium will be able to connect your Blotout event-based tracking to our transactional level data from your eCommerce store for near live-time reporting!
diff --git a/data-inputs/platform-integration-instructions/chargebee-integration.mdx b/data-inputs/platform-integration-instructions/chargebee-integration.mdx
index 3d95b0b..4e5d2cd 100644
--- a/data-inputs/platform-integration-instructions/chargebee-integration.mdx
+++ b/data-inputs/platform-integration-instructions/chargebee-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Chargebee - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Chargebee data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Chargebee data to SourceMedium.
### Requirements
@@ -31,4 +30,4 @@ icon: 'plug'
### Additional information
-- [Chargebee API Keys](https://www.chargebee.com/docs/2.0/api_keys.html)
\ No newline at end of file
+- [Chargebee API Keys](https://www.chargebee.com/docs/2.0/api_keys.html)
diff --git a/data-inputs/platform-integration-instructions/criteo-integration.mdx b/data-inputs/platform-integration-instructions/criteo-integration.mdx
index ba9b688..43cd510 100644
--- a/data-inputs/platform-integration-instructions/criteo-integration.mdx
+++ b/data-inputs/platform-integration-instructions/criteo-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Criteo - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Criteo data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Criteo data to SourceMedium.
### Requirements
@@ -32,4 +31,4 @@ icon: 'plug'

-Our team will accept the invitation and begin ingesting your Criteo data.
\ No newline at end of file
+Our team will accept the invitation and begin ingesting your Criteo data.
diff --git a/data-inputs/platform-integration-instructions/elevar-integration.mdx b/data-inputs/platform-integration-instructions/elevar-integration.mdx
index 1953e31..6719ff7 100644
--- a/data-inputs/platform-integration-instructions/elevar-integration.mdx
+++ b/data-inputs/platform-integration-instructions/elevar-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Elevar - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Elevar data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Elevar data to SourceMedium.
### Requirements
diff --git a/data-inputs/platform-integration-instructions/fairing-integration.mdx b/data-inputs/platform-integration-instructions/fairing-integration.mdx
index 84dded5..01dfa00 100644
--- a/data-inputs/platform-integration-instructions/fairing-integration.mdx
+++ b/data-inputs/platform-integration-instructions/fairing-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Fairing - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Fairing data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Fairing post-purchase survey data to SourceMedium.
### Requirements
@@ -12,4 +11,4 @@ icon: 'plug'
### Steps
-1. Please let us know that you’re a customer of Fairing and will take care of the rest!
\ No newline at end of file
+1. Please let us know that you’re a customer of Fairing and will take care of the rest!
diff --git a/data-inputs/platform-integration-instructions/fermat-integration.mdx b/data-inputs/platform-integration-instructions/fermat-integration.mdx
index 3484127..33102b3 100644
--- a/data-inputs/platform-integration-instructions/fermat-integration.mdx
+++ b/data-inputs/platform-integration-instructions/fermat-integration.mdx
@@ -1,16 +1,26 @@
---
-title: 'FERMÀT - Integration Instructions'
-description: ''
-icon: 'plug'
+title: "FERMÀT - Integration Instructions"
+description: "How to ensure orders from the Fermat Shopify app are detected correctly in SourceMedium."
+icon: "plug"
---
-## Follow this integration guide to connect your FERMÀT data to SourceMedium.
+## Follow this integration guide to connect Fermat data to SourceMedium
+
+FERMÀT is a Shopify app. SourceMedium detects Fermat-attributed orders via Shopify order metadata.
### Requirements
-- Customer of FERMÀT
+- A working [Shopify integration](/data-inputs/platform-integration-instructions/shopify-integration)
+- Admin access to Shopify to confirm the Fermat app is installed and active
### Steps
-1. Connect the FERMÀT app to your Shopify store, and that’s it!
- 1. We automatically pull the data directly from FERMÀT into SourceMedium
\ No newline at end of file
+1. Confirm Shopify is connected to SourceMedium.
+2. Confirm the Fermat Shopify app is installed and being used for your storefront experience.
+3. Email **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)** to confirm your store uses FERMÀT so we can validate detection and reporting.
+
+### Troubleshooting
+
+- If Fermat orders appear in Shopify but are not showing as expected in SourceMedium, contact **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)** and include:
+ - Your Shopify store name
+ - Example order IDs and order processed dates
diff --git a/data-inputs/platform-integration-instructions/ga-universal-integration.mdx b/data-inputs/platform-integration-instructions/ga-universal-integration.mdx
index 896c56d..72227ed 100644
--- a/data-inputs/platform-integration-instructions/ga-universal-integration.mdx
+++ b/data-inputs/platform-integration-instructions/ga-universal-integration.mdx
@@ -1,11 +1,16 @@
---
title: '[Legacy] Google Analytics Universal - Integration Instructions'
-description: ''
+description: "Legacy instructions for connecting Google Analytics Universal (UA) to SourceMedium"
icon: 'plug'
---
## Follow this integration guide to connect your Google Analytics data to SourceMedium.
+
+Universal Analytics (UA) has been sunset by Google and is no longer available for ongoing use. This page is kept for historical reference only.
+Use the [Google Analytics 4 integration](/data-inputs/platform-integration-instructions/ga4-integration) for active tracking.
+
+
### Requirements
- **Admin access** for Google Analytics - [**learn more about Google Analytics roles**](https://support.google.com/analytics/answer/9305587?hl=en)
@@ -15,8 +20,8 @@ icon: 'plug'
1. Provide access to Google Analytics to SourceMedium
1. Login to your **Google Analytics Admin** > **View**, and navigate to **View Access Management** to select a view for data ingestion
- .png)
+ 
- 2. Add [](https://www.notion.so/ga-sourceMedium-1b424f6a28a64b1292c068cf7a10040c?pvs=21)integrations4@sourcemedium.com as a new user and set the permissions to **Viewer** as seen in the screenshot below. This will send an email to invite SourceMedium to integrate your data to your dashboards
+ 2. Add `integrations4@sourcemedium.com` as a new user and set the permissions to **Viewer** as seen in the screenshot below. This will send an email to invite SourceMedium to integrate your data to your dashboards
- .png)
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-integration-instructions/ga4-integration.mdx b/data-inputs/platform-integration-instructions/ga4-integration.mdx
index 85a198c..cb1d25d 100644
--- a/data-inputs/platform-integration-instructions/ga4-integration.mdx
+++ b/data-inputs/platform-integration-instructions/ga4-integration.mdx
@@ -30,4 +30,4 @@ icon: 'plug'

4. Click **Add**.
-2. Once SourceMedium receives the email notification, we will connect and begin to integrate your GA4 data to your dashboard.
\ No newline at end of file
+2. Once SourceMedium receives the email notification, we will connect and begin to integrate your GA4 data to your dashboard.
diff --git a/data-inputs/platform-integration-instructions/global-e-integration.mdx b/data-inputs/platform-integration-instructions/global-e-integration.mdx
index 083038b..a8d4870 100644
--- a/data-inputs/platform-integration-instructions/global-e-integration.mdx
+++ b/data-inputs/platform-integration-instructions/global-e-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Global-E - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Global-E data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect ****Global-e data in SourceMedium.****
### Requirements
@@ -16,4 +15,4 @@ Merchants use Global-e within Shopify to help manage international sales and tax
SourceMedium has partnered with Global-e to retrieve and separate of the duties & taxes from Gross Sales within our data model and pre-built Looker reports.
-Reach out to your SourceMedium manager to have this feature enabled.
\ No newline at end of file
+Reach out to your SourceMedium manager to have this feature enabled.
diff --git a/data-inputs/platform-integration-instructions/google-ads-integration.mdx b/data-inputs/platform-integration-instructions/google-ads-integration.mdx
index 08bb75d..1e88d26 100644
--- a/data-inputs/platform-integration-instructions/google-ads-integration.mdx
+++ b/data-inputs/platform-integration-instructions/google-ads-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Google Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Google Ads data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Google Ads data to SourceMedium.
### Requirements
diff --git a/data-inputs/platform-integration-instructions/google-search-console-integration.mdx b/data-inputs/platform-integration-instructions/google-search-console-integration.mdx
index 5e71d77..08ed5ec 100644
--- a/data-inputs/platform-integration-instructions/google-search-console-integration.mdx
+++ b/data-inputs/platform-integration-instructions/google-search-console-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Google Search Console - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Google Search Console data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Google Search Console data to SourceMedium.
### Requirements
@@ -22,4 +21,4 @@ icon: 'plug'
3. Grant SourceMedium access by adding integrations4@sourcemedium.com and set permission to **Restricted**, and click **ADD**
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-integration-instructions/gorgias-integration.mdx b/data-inputs/platform-integration-instructions/gorgias-integration.mdx
index d13a48b..97631fc 100644
--- a/data-inputs/platform-integration-instructions/gorgias-integration.mdx
+++ b/data-inputs/platform-integration-instructions/gorgias-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'Gorgias (Beta) - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Gorgias (Beta) data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Gorgias data to SourceMedium.
### Requirements
@@ -28,4 +27,4 @@ icon: 'plug'
1. Fill in the Name as SourceMedium, Email as integrations@sourcemedium.com, and make sure to select the **Role as Admin Agent**
-
\ No newline at end of file
+
diff --git a/data-inputs/platform-integration-instructions/hubspot-integration.mdx b/data-inputs/platform-integration-instructions/hubspot-integration.mdx
index b5c7d0c..245770b 100644
--- a/data-inputs/platform-integration-instructions/hubspot-integration.mdx
+++ b/data-inputs/platform-integration-instructions/hubspot-integration.mdx
@@ -1,9 +1,8 @@
---
title: '[Premium] HubSpot Integration - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your [Premium] HubSpot Integration data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your HubSpot data to SourceMedium.
### Requirements
@@ -29,4 +28,4 @@ To lean more about HubSpot user roles and permissions, please visit their [HubSp
3. After the integration is complete, **remove** **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)** **as a super admin**
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-integration-instructions/impact-integration.mdx b/data-inputs/platform-integration-instructions/impact-integration.mdx
index a4b40b8..e9867a6 100644
--- a/data-inputs/platform-integration-instructions/impact-integration.mdx
+++ b/data-inputs/platform-integration-instructions/impact-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Impact Radius - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Impact Radius data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Impact Radius data to SourceMedium.
### **Requirements**
@@ -27,4 +26,4 @@ icon: 'plug'
### **Additional information**
- - [**Impact's REST API**](https://impact.com/partnerships/get-connected-with-rest-api/)
\ No newline at end of file
+ - [**Impact's REST API**](https://impact.com/partnerships/get-connected-with-rest-api/)
diff --git a/data-inputs/platform-integration-instructions/klaviyo-integration.mdx b/data-inputs/platform-integration-instructions/klaviyo-integration.mdx
index 9ab5354..ead73de 100644
--- a/data-inputs/platform-integration-instructions/klaviyo-integration.mdx
+++ b/data-inputs/platform-integration-instructions/klaviyo-integration.mdx
@@ -1,9 +1,8 @@
---
title: '[Premium] Klaviyo Integration - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your [Premium] Klaviyo Integration data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Klaviyo data to SourceMedium.
### Requirements
@@ -40,4 +39,4 @@ icon: 'plug'
### Additional resources
-- [Manage your Klaviyo API Keys](https://help.klaviyo.com/hc/en-us/articles/115005062267-How-to-Manage-Your-Account-s-API-Keys)
\ No newline at end of file
+- [Manage your Klaviyo API Keys](https://help.klaviyo.com/hc/en-us/articles/115005062267-How-to-Manage-Your-Account-s-API-Keys)
diff --git a/data-inputs/platform-integration-instructions/knocommerce-integration.mdx b/data-inputs/platform-integration-instructions/knocommerce-integration.mdx
index 5ee6892..4f45539 100644
--- a/data-inputs/platform-integration-instructions/knocommerce-integration.mdx
+++ b/data-inputs/platform-integration-instructions/knocommerce-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'KnoCommerce - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your KnoCommerce data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your KnoCommerce post-purchase survey data to SourceMedium.
### Requirements
@@ -12,4 +11,4 @@ icon: 'plug'
### Steps
-1. Please let us know that you’re a customer of KnoCommerce and will take care of the rest!
\ No newline at end of file
+1. Please let us know that you’re a customer of KnoCommerce and will take care of the rest!
diff --git a/data-inputs/platform-integration-instructions/littledata-integration.mdx b/data-inputs/platform-integration-instructions/littledata-integration.mdx
index e661033..0afe6de 100644
--- a/data-inputs/platform-integration-instructions/littledata-integration.mdx
+++ b/data-inputs/platform-integration-instructions/littledata-integration.mdx
@@ -1,13 +1,12 @@
---
title: '[Beta] Littledata - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your [Beta] Littledata data to SourceMedium.'
icon: 'plug'
---
-
### Requirements
- This integration is currently in BETA (reach out to support to learn more)
### Background
-SourceMedium will be able to connect your Littledata event-based tracking to our transactional level data from your eCommerce store for near live-time reporting!
\ No newline at end of file
+SourceMedium will be able to connect your Littledata event-based tracking to our transactional level data from your eCommerce store for near live-time reporting!
diff --git a/data-inputs/platform-integration-instructions/loop-integration.mdx b/data-inputs/platform-integration-instructions/loop-integration.mdx
index c4bbe76..062c5fd 100644
--- a/data-inputs/platform-integration-instructions/loop-integration.mdx
+++ b/data-inputs/platform-integration-instructions/loop-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Loop - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Loop data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Loop subscriptions data to SourceMedium.
### Requirements
@@ -14,4 +13,4 @@ icon: 'plug'
### Steps
1. Connect the Loop app to your Shopify store, and that’s it!
- 1. We automatically pull the data directly from Loop into SourceMedium
\ No newline at end of file
+ 1. We automatically pull the data directly from Loop into SourceMedium
diff --git a/data-inputs/platform-integration-instructions/mailchimp-integration.mdx b/data-inputs/platform-integration-instructions/mailchimp-integration.mdx
deleted file mode 100644
index b9400f5..0000000
--- a/data-inputs/platform-integration-instructions/mailchimp-integration.mdx
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: '[Premium] Mailchimp - Integration Instructions'
-description: ''
-icon: 'plug'
----
-
-## Follow this integration guide to connect your Mailchimp data to SourceMedium.
-
-### Requirements
-
-- **Manager or Admin access** for Mailchimp to be able to generate and view API keys
-
-### Steps
-
-1. Create a Mailchimp API key
- 1. Sign into your Mailchimp account
- 2. Click the user menu (bottom left of the page), then click **Account**
-
- 
-
- 3. On the **Account** page, click **Extras > API Keys**
-
- 
-
- 4. On the **API Keys** page, click the **Create API Key** button to create an API key
-
- 
-
- 5. In the **Label** column, click the pencil icon next to the API key you just created
- 1. Enter a label for the API key. For example: SourceMedium integration
- 6. Click **Save API Key**
-2. Email the generated API key to SourceMedium at integrations@sourcemedium.com
-
-### Additional resources
-
-- [About Mailchimp API keys](https://mailchimp.com/help/about-api-keys/#Find_or_generate_your_API_key)
\ No newline at end of file
diff --git a/data-inputs/platform-integration-instructions/meta-integration.mdx b/data-inputs/platform-integration-instructions/meta-integration.mdx
index 4a10bb9..6795dbb 100644
--- a/data-inputs/platform-integration-instructions/meta-integration.mdx
+++ b/data-inputs/platform-integration-instructions/meta-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Meta Ads (Facebook) - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Meta Ads (Facebook) data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Meta Ads data to SourceMedium.
### Requirements
@@ -41,4 +40,12 @@ icon: 'plug'

-**Please Note:** *SourceMedium reports Meta data on an account-level default of 7-day click, 1-day view. We sometimes see different windows set between campaigns, which can cause confusion when validating vs. the Meta UI.*
\ No newline at end of file
+**Please Note:**
+- **Due to recent API changes, Meta Ads data is limited to the past 36 months from the date of connection creation.**
+- By default, SourceMedium reports Meta data **on 7-day click, 1-day view.**
+ - We offer alternative windows for Meta Ads reported revenue and conversions. These can be configured with the help of a SourceMedium Customer Solutions Analyst.
+ - We offer the following alternative revenue and conversion windows for Meta Ads:
+ - 1-day click
+ - 7-day click
+ - 1-day view
+ - 7-day view
diff --git a/data-inputs/platform-integration-instructions/mntn-integration.mdx b/data-inputs/platform-integration-instructions/mntn-integration.mdx
index a49482f..765c4eb 100644
--- a/data-inputs/platform-integration-instructions/mntn-integration.mdx
+++ b/data-inputs/platform-integration-instructions/mntn-integration.mdx
@@ -1,9 +1,8 @@
---
title: 'MNTN - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your MNTN data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your MNTN data to SourceMedium.
### Requirements
@@ -28,4 +27,4 @@ icon: 'plug'
5. Send an email to SourceMedium at integrations@sourcemedium.com containing your store's name, the platform we are connecting with (in this case MNTN) and your MNTN API Key
-Once we receive your email, we will connect with your MNTN data via the API as soon as possible. Once we are connected, we will delete the email contining your key for security purposes.
\ No newline at end of file
+Once we receive your email, we will connect with your MNTN data via the API as soon as possible. Once we are connected, we will delete the email contining your key for security purposes.
diff --git a/data-inputs/platform-integration-instructions/outbrain-integration.mdx b/data-inputs/platform-integration-instructions/outbrain-integration.mdx
index abe878e..b304921 100644
--- a/data-inputs/platform-integration-instructions/outbrain-integration.mdx
+++ b/data-inputs/platform-integration-instructions/outbrain-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Outbrain - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Outbrain data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Outbrain data to SourceMedium.
### Requirements
@@ -26,4 +25,4 @@ icon: 'plug'
Click on **Invite** to finish the process.
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-integration-instructions/pepperjam-integration.mdx b/data-inputs/platform-integration-instructions/pepperjam-integration.mdx
index f2b7b80..f2620bb 100644
--- a/data-inputs/platform-integration-instructions/pepperjam-integration.mdx
+++ b/data-inputs/platform-integration-instructions/pepperjam-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Pepperjam - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Pepperjam data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Pepperjam data to SourceMedium.
### Requirements
@@ -19,4 +18,4 @@ icon: 'plug'
3. Click **Generate New Key**
4. Your API key will display
2. Share the API key with SourceMedium
- 1. Email the API key to [**integrations@sourcemedium.com**](mailto:integrations@sourcemedium.com)
\ No newline at end of file
+ 1. Email the API key to [**integrations@sourcemedium.com**](mailto:integrations@sourcemedium.com)
diff --git a/data-inputs/platform-integration-instructions/pinterest-integration.mdx b/data-inputs/platform-integration-instructions/pinterest-integration.mdx
index a677c34..a879367 100644
--- a/data-inputs/platform-integration-instructions/pinterest-integration.mdx
+++ b/data-inputs/platform-integration-instructions/pinterest-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Pinterest Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Pinterest Ads data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Pinterest Ads data to SourceMedium.
### Requirements
@@ -39,4 +38,4 @@ icon: 'plug'
### **Additional information**
-- If you're having trouble adding SourceMedium as a partner, reference Pinterest's [Manage Partners](https://help.pinterest.com/en/business/article/share-and-manage-access-to-your-ad-accounts) help article
\ No newline at end of file
+- If you're having trouble adding SourceMedium as a partner, reference Pinterest's [Manage Partners](https://help.pinterest.com/en/business/article/share-and-manage-access-to-your-ad-accounts) help article
diff --git a/data-inputs/platform-integration-instructions/recharge-integration.mdx b/data-inputs/platform-integration-instructions/recharge-integration.mdx
index 28ac827..94f0f10 100644
--- a/data-inputs/platform-integration-instructions/recharge-integration.mdx
+++ b/data-inputs/platform-integration-instructions/recharge-integration.mdx
@@ -31,7 +31,7 @@ icon: 'plug'
1. In the **Permission** section, select the following permissions for **Read Access:**
- 
+ 
3. When all permissions are selected, click **Create an API token** to obtain your API key ****
@@ -47,4 +47,4 @@ Common troubleshooting steps in case your API key does not correctly load
- The API tokens must be enabled manually by ReCharge. Learn how to enable the keys in ReCharge’s [**documentation**](https://support.rechargepayments.com/hc/en-us/articles/360008829993)
- If you've reached ReCharge’s hard limit on the number of API tokens
- Share one of your existing API keys with similar permission scopes
-- Check [here](https://www.notion.so/Why-doesn-t-ReCharge-subscription-data-match-Source-Medium-Reports-2e4127049cbe406babe7a56ac717dec3?pvs=21) for additional reasons why your ReCharge data might not match SourceMedium reports
\ No newline at end of file
+- Check [here](/help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium) for additional reasons why your ReCharge data might not match SourceMedium reports
diff --git a/data-inputs/platform-integration-instructions/reddit-integration.mdx b/data-inputs/platform-integration-instructions/reddit-integration.mdx
index c74500c..6e64ff9 100644
--- a/data-inputs/platform-integration-instructions/reddit-integration.mdx
+++ b/data-inputs/platform-integration-instructions/reddit-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Reddit Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Reddit Ads data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Reddit Ads data to SourceMedium.
### Steps
@@ -22,9 +21,9 @@ icon: 'plug'
- Select Invite
- Note: Only the account owner and users with administrator permissions can invite new contributors.
-3. Contact your Reddit Ads account manger and request that both you and Source Medium be given Ads API Access to your account
+3. Contact your Reddit Ads account manger and request that both you and SourceMedium be given Ads API Access to your account
- If asked for SourceMedium's account info:
- Email: integrations@sourcemedium.com
- Username: SourceMediumInt
4. Once you and SourceMedium have been given API access, please reach out to us and let us know via Slack or Email
- - Please let us know your Reddit Ad purchase window settings, so we can have our purchase conversions use this same window
\ No newline at end of file
+ - Please let us know your Reddit Ad purchase window settings, so we can have our purchase conversions use this same window
diff --git a/data-inputs/platform-integration-instructions/shareasale-integration.mdx b/data-inputs/platform-integration-instructions/shareasale-integration.mdx
index 98f6e87..2777b84 100644
--- a/data-inputs/platform-integration-instructions/shareasale-integration.mdx
+++ b/data-inputs/platform-integration-instructions/shareasale-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'ShareASale - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your ShareASale data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your ShareASale data to SourceMedium.
### Requirements
@@ -20,4 +19,4 @@ icon: 'plug'
b. Note your **Token**, **API Secret** and **Merchant ID**
-2. Email the **Token, API Secret, Merchant ID** credentials to integrations@sourcemedium.com
\ No newline at end of file
+2. Email the **Token, API Secret, Merchant ID** credentials to integrations@sourcemedium.com
diff --git a/data-inputs/platform-integration-instructions/shopify-integration.mdx b/data-inputs/platform-integration-instructions/shopify-integration.mdx
index aebcb95..ca35f9a 100644
--- a/data-inputs/platform-integration-instructions/shopify-integration.mdx
+++ b/data-inputs/platform-integration-instructions/shopify-integration.mdx
@@ -8,7 +8,7 @@ icon: 'plug'
### Requirements
- **Admin access** for **Shopify** to be able to accept partner request
-- If you require a **Collaborator Request Code**, please share this code with [integrations@sourcemedium.com](https://www.notion.so/05f24bf61df64af79972bc9096e72bd5?pvs=21). You can find code on the **********************************************Plan and Permissions********************************************** page of your Shopify Admin. [Learn more.](https://help.shopify.com/en/partners/dashboard/managing-stores/request-access)
+- If you require a **Collaborator Request Code**, please share this code with [integrations@sourcemedium.com](mailto:integrations@sourcemedium.com). You can find the code on the **Plan and Permissions** page of your Shopify Admin. [Learn more.](https://help.shopify.com/en/partners/dashboard/managing-stores/request-access)
### Steps
@@ -27,4 +27,4 @@ icon: 'plug'

- 3. Once the invite is successfully accepted, SourceMedium will show up under your list of **Collaborator accounts** at `https://{{STORE}}.myshopify.com/admin/settings/account`
\ No newline at end of file
+ 3. Once the invite is successfully accepted, SourceMedium will show up under your list of **Collaborator accounts** at `https://{{STORE}}.myshopify.com/admin/settings/account`
diff --git a/data-inputs/platform-integration-instructions/snapchat-integration.mdx b/data-inputs/platform-integration-instructions/snapchat-integration.mdx
index 0c291b7..a453641 100644
--- a/data-inputs/platform-integration-instructions/snapchat-integration.mdx
+++ b/data-inputs/platform-integration-instructions/snapchat-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Snapchat - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Snapchat data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Snapchat Ads data to SourceMedium.
### **Requirements**
@@ -31,4 +30,4 @@ icon: 'plug'
### Additional information
-- To help troubleshoot issues relating to adding new members, check the **[Snapchat Manage Members article](https://businesshelp.snapchat.com/s/article/manage-members?language=en_US)**
\ No newline at end of file
+- To help troubleshoot issues relating to adding new members, check the **[Snapchat Manage Members article](https://businesshelp.snapchat.com/s/article/manage-members?language=en_US)**
diff --git a/data-inputs/platform-integration-instructions/stay-ai-integration.mdx b/data-inputs/platform-integration-instructions/stay-ai-integration.mdx
index 5c95b30..4454624 100644
--- a/data-inputs/platform-integration-instructions/stay-ai-integration.mdx
+++ b/data-inputs/platform-integration-instructions/stay-ai-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Stay AI - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Stay AI data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Stay AI data to SourceMedium.
### Requirements
@@ -14,4 +13,4 @@ icon: 'plug'
### Steps
1. Connect the Stay AI app to your Shopify store, and that’s it!
- 1. We automatically pull the data directly from Stay AI into SourceMedium
\ No newline at end of file
+ 1. We automatically pull the data directly from Stay AI into SourceMedium
diff --git a/data-inputs/platform-integration-instructions/stripe-integration.mdx b/data-inputs/platform-integration-instructions/stripe-integration.mdx
index ea62972..83e3d87 100644
--- a/data-inputs/platform-integration-instructions/stripe-integration.mdx
+++ b/data-inputs/platform-integration-instructions/stripe-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Stripe - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Stripe data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Stripe data to SourceMedium.
### Requirements
@@ -48,4 +47,4 @@ icon: 'plug'
c. Invite **[integrations@sourcemedium.com](mailto:integrations@sourcemedium.com)** as a **View only** user
-
\ No newline at end of file
+
diff --git a/data-inputs/platform-integration-instructions/taboola-integration.mdx b/data-inputs/platform-integration-instructions/taboola-integration.mdx
index e17b0d6..c3be034 100644
--- a/data-inputs/platform-integration-instructions/taboola-integration.mdx
+++ b/data-inputs/platform-integration-instructions/taboola-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Taboola - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Taboola data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Taboola data to SourceMedium.
### Requirements
@@ -15,4 +14,4 @@ icon: 'plug'
- If you already have your **API credentials** (`client_id` and `client_secret`), send them to integrations@sourcemedium.com
- If you do not have your API credentials.
- - Reach out to your **Taboola Account Manager** for **API credentials**, or contact support@taboola.com and request for them to send the **API Credentials** to integrations@sourcemedium.com
\ No newline at end of file
+ - Reach out to your **Taboola Account Manager** for **API credentials**, or contact support@taboola.com and request for them to send the **API Credentials** to integrations@sourcemedium.com
diff --git a/data-inputs/platform-integration-instructions/tapcart-integration.mdx b/data-inputs/platform-integration-instructions/tapcart-integration.mdx
index 2031857..e27bc7d 100644
--- a/data-inputs/platform-integration-instructions/tapcart-integration.mdx
+++ b/data-inputs/platform-integration-instructions/tapcart-integration.mdx
@@ -1,11 +1,10 @@
---
title: 'Tapcart (Beta) - Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Tapcart (Beta) data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Tapcart data to SourceMedium.
### Requirements
-- This integration is currently in BETA (reach out to support to learn more)
\ No newline at end of file
+- This integration is currently in BETA (reach out to support to learn more)
diff --git a/data-inputs/platform-integration-instructions/tatari-integration.mdx b/data-inputs/platform-integration-instructions/tatari-integration.mdx
index 16c362e..706bf28 100644
--- a/data-inputs/platform-integration-instructions/tatari-integration.mdx
+++ b/data-inputs/platform-integration-instructions/tatari-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'Tatari - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your Tatari data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your Tatari data to SourceMedium.
### Requirements
@@ -13,4 +12,4 @@ icon: 'plug'
### Steps
-1. Please connect your Tatari account rep and will take it from there!
\ No newline at end of file
+1. Please connect your Tatari account rep and will take it from there!
diff --git a/data-inputs/platform-integration-instructions/tiktok-integration.mdx b/data-inputs/platform-integration-instructions/tiktok-integration.mdx
index c8319ee..5768151 100644
--- a/data-inputs/platform-integration-instructions/tiktok-integration.mdx
+++ b/data-inputs/platform-integration-instructions/tiktok-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'TikTok - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your TikTok data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your TikTok data to SourceMedium.
### Requirements
@@ -29,4 +28,4 @@ icon: 'plug'
### Additional resources
- [Add Users to TikTok Business Center](https://ads.tiktok.com/help/article?aid=12790)
-- [Managing permissions](https://ads.tiktok.com/help/article?aid=12791)
\ No newline at end of file
+- [Managing permissions](https://ads.tiktok.com/help/article?aid=12791)
diff --git a/data-inputs/platform-integration-instructions/x-integration.mdx b/data-inputs/platform-integration-instructions/x-integration.mdx
index 42ed87e..a6acc65 100644
--- a/data-inputs/platform-integration-instructions/x-integration.mdx
+++ b/data-inputs/platform-integration-instructions/x-integration.mdx
@@ -1,10 +1,9 @@
---
title: 'X Ads - Integration Instructions'
sidebarTitle: 'Integration Instructions'
-description: ''
+description: 'Follow this integration guide to connect your X Ads data to SourceMedium.'
icon: 'plug'
---
-
## Follow this integration guide to connect your X Ads data to SourceMedium.
### Requirements
@@ -30,4 +29,4 @@ icon: 'plug'
3. The following message should appear if your changes are saved successfully
- 
\ No newline at end of file
+ 
diff --git a/data-inputs/platform-overviews/amazon-ads-platform-overview.mdx b/data-inputs/platform-overviews/amazon-ads-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/amazon-dsp-platform-overview.mdx b/data-inputs/platform-overviews/amazon-dsp-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/amazon-sc-platform-overview.mdx b/data-inputs/platform-overviews/amazon-sc-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/amazon-vc-platform-overview.mdx b/data-inputs/platform-overviews/amazon-vc-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/autopilot-platform-overview.mdx b/data-inputs/platform-overviews/autopilot-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/awin-platform-overview.mdx b/data-inputs/platform-overviews/awin-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/bing-platform-overview.mdx b/data-inputs/platform-overviews/bing-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/blotout-platform-overview.mdx b/data-inputs/platform-overviews/blotout-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/chargebee-platform-overview.mdx b/data-inputs/platform-overviews/chargebee-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/criteo-platform-overview.mdx b/data-inputs/platform-overviews/criteo-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/elevar-platform-overview.mdx b/data-inputs/platform-overviews/elevar-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/fairing-platform-overview.mdx b/data-inputs/platform-overviews/fairing-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/fermat-platform-overview.mdx b/data-inputs/platform-overviews/fermat-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/ga-universal-platform-overview.mdx b/data-inputs/platform-overviews/ga-universal-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/ga4-platform-overview.mdx b/data-inputs/platform-overviews/ga4-platform-overview.mdx
deleted file mode 100644
index 8620710..0000000
--- a/data-inputs/platform-overviews/ga4-platform-overview.mdx
+++ /dev/null
@@ -1,82 +0,0 @@
----
-title: 'GA4 - Platform Overview'
-sidebarTitle: 'Platform Overview'
-description: 'Information on data availability, ingestion, cleaning & transformation, data enrichment and additional use-cases & capabilities'
-icon: 'database'
----
-
-### What GA4 data is available in SourceMedium?
-
-While SourcMedium mainly uses GA4 data for enriched attribution of orders & customer acquisition (see Data Enrichment section), we also ingest data related
-to your site traffic -- which we pair against real orders data (as-reported by your sales platform) to build an accurate CVR picture.
-
-Keep in mind that the data provided by GA is only as good as the tracking technology being used, which can be circumvented by customers using ad
-blockers or faulty tracking. For this reason, we use Shopify as our source of truth and use GA4 to enrich that data.
-
-
- Embed / link out to metric & dimension docs
-
-
-
- When integrating data, it's important to decide on a "most trustworthy" data source to use as a foundation (also called "source of truth" data).
- At SourceMedium we use Shopify data as our source of truth for all sales data, as Shopify data is robust and represents real financial transactions
- (meaning we won't be missing records of sales).
-
- When we integrate Google Analytics data with Shopify data, we trust Shopify more than Google Analytics when it comes to the last-click attribution of
- that order (where that order came from based on UTM parameters) - meaning if the two sources disagree, we will report what Shopify says. This
- hierarchy of trust is called our “Attribution Waterfall.” In short, when we report this integrated data, we are showing Shopify data which has been
- enriched and expanded by Google Analytics.
-
- This enrichment can fill in gaps in both data sources — SourceMedium can regularly provide attribution for 10-30% more orders than Google Analytics
- or Shopify on their own.
-
-
-### Where is GA4 data surfaced in SourceMedium?
-
- - [Executive Summary](/data-activation/managed-bi-v1/modules/executive-summary-module)
- - Site traffic (`sessions`) and `CVR`
- - [Traffic Deep Dive](/data-activation/managed-bi-v1/modules/traffic-deep-dive-module)
- - Traffic, engagement, and ecommerce performance by channel, device, and more
- - Most data available in GA4 native reporting is available to surface here
- - Visit our [Template Gallery](https://lookerstudio.google.com/reporting/2853e13c-3071-44dd-8e24-8f9d6f68381c/page/p_hbjrx5v6wc), or reach out to the Customer Solutions team via Slack or email for more info!
- - [Orders Deep Dive](/data-activation/managed-bi-v1/modules/orders-deep-dive-module)
- - GA4-enriched last-click attribution of orders data
- - [Product Performance](/data-activation/managed-bi-v1/modules/product-performance-module)
- - GA4-enriched last-click attribution for line-item sales data
- - [New Customer Analysis](/data-activation/managed-bi-v1/modules/new-customer-analysis-module)
- - GA4-enriched customer acquisition last-click attribution
- - [Customers - Last Order Analysis](/data-activation/managed-bi-v1/modules/last-order-analysis-module)
- - Latest order & 1st to last order GA4-enriched attribution comparison
-
-
-
- - `[order_details]({link out to specific table docs})`
- - `[product_performance]({link out to specific table docs})`
- - `[customer_details]({link out to specific table docs})`
- - `[executive_summary]({link out to specific table docs})`
-
-
-
-### Additional information
-**Data Freshness:**
-SourceMedium attempts to ingest data from the GA4 API every 6 hours, and fully transformed data should be available within data tables &
-dashboards by the next day.
-
-**Other data clarifications: data nuances & good-to-knows**
-
-
- - `(Direct) / (none)` means either customers visited your website directly (manually typing in the URL or hitting a bookmark) or something forced UTM tracking to break.
- - `(None) / (none)` traffic refers to visitors whose UTM source and medium values are both `null` and therefore cannot be identified by Google Analytics.
- If you're seeing one these `source / medium` values as a large bucket of your attribution, usually it means something can be improved! You can read up
- on how to improve your UTM tracking in Google Analytics [here](/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution).
-
-
- It is important to note that Google Analytics may not be able to distinguish between new and returning customers, as it does not have a total history
- of your new versus repeat customers. To address this, SourceMedium has ingested historic data for your business to match a customer against those that
- have been ingested to determine if that customer is new or returning.
-
-
- Given SourceMedium stitches your GA4 data with your sales data to build the most accurate picture of attribution, often times there are reporting differences
- between SourceMedium order & customer attribution and native GA4 & Shopify reporting.
-
-
\ No newline at end of file
diff --git a/data-inputs/platform-overviews/google-search-console-platform-overview.mdx b/data-inputs/platform-overviews/google-search-console-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/gorgias-platform-overview.mdx b/data-inputs/platform-overviews/gorgias-platform-overview.mdx
deleted file mode 100644
index df2180f..0000000
--- a/data-inputs/platform-overviews/gorgias-platform-overview.mdx
+++ /dev/null
@@ -1,127 +0,0 @@
-## Overview
-
-The Customer Support data models provide analytics-ready transformations of your [Gorgias](https://www.gorgias.com/) customer support platform data in BigQuery. These models enable you to track, analyze, and visualize your customer support performance through our [pre-built dashboard template](https://lookerstudio.google.com/s/iEvv2YdLPiM) or custom analysis via SQL.
-
-The integration transforms your raw Gorgias data into a structured, optimized format that follows SourceMedium's unified data model approach, ensuring consistent metrics definitions across all customer support platforms.
-
-
-
-## Data Location
-
-All Customer Support data is available in your BigQuery instance under:
-```
-[sm-{{ company_id }}].[sm_experimental].obt_customer_support_tickets*
-```
-NOTE that this will eventually be moved to `sm_transformed_v2` dataset once the schema is more finalized.
-
-The primary reporting table is `obt_customer_support_tickets`, which contains all metrics needed for dashboard visualizations.
-
-## Key Metrics
-
-The Customer Support data models track several key performance indicators:
-
-### Ticket Performance
-- **Average Resolution Time**: The average time (in hours) between ticket creation and resolution
-- **One-Touch Resolution Rate**: Percentage of tickets resolved with a single agent interaction
-- **Open Tickets**: Total number of tickets currently open
-- **Resolution Distribution**: Distribution of tickets by resolution time (0-3 hours, 3-6 hours, etc.)
-
-### Customer Satisfaction
-- **CSAT Score**: Average customer satisfaction rating (1-5 scale)
-- **CSAT Rating Distribution**: Breakdown of tickets by satisfaction rating
-- **CSAT Survey Response Rate**: Percentage of closed tickets with completed CSAT surveys
-
-### Volume & Channel Analysis
-- **Tickets by Channel**: Distribution across channels (email, chat, social media, etc.)
-- **Tickets Created/Closed**: Total tickets created/closed in the selected period
-- **Messages per Ticket**: Average number of messages exchanged per ticket
-
-## Key Tables & Fields
-
-### obt_customer_support_tickets
-
-The primary reporting table for customer support analysis.
-
-| Field | Description |
-|-------|-------------|
-| `sm_store_id` | SourceMedium Customer ID |
-| `source_system` | The system where the ticket originated (e.g., "gorgias") |
-| `ticket_source` | The source from which the ticket originated |
-| `ticket_channel` | The communication channel (email, chat, social, etc.) |
-| `ticket_created_at_local_datetime` | Local datetime when the ticket was created |
-| `ticket_closed_at_local_datetime` | Local datetime when the ticket was closed |
-| `tickets_created` | Count of tickets created (1 or 0) |
-| `tickets_closed` | Count of tickets closed (1 or 0) |
-| `one_touch_tickets` | Whether the ticket was resolved in a single interaction |
-| `ticket_resolution_time_hours` | Time taken to resolve the ticket in hours |
-
-### dim_customer_support_tickets
-
-Detailed dimension table containing ticket attributes and metadata.
-
-| Field | Description |
-|-------|-------------|
-| `ticket_id` | Unique identifier for the ticket |
-| `ticket_external_id` | External identifier used in Gorgias |
-| `ticket_created_at` | UTC timestamp when the ticket was created |
-| `ticket_closed_at` | UTC timestamp when the ticket was closed |
-| `ticket_subject` | The subject line of the ticket |
-| `ticket_status` | Current status of the ticket (open, closed, pending) |
-| `ticket_priority` | Priority level assigned to the ticket |
-| `ticket_channel` | Communication channel used |
-| `ticket_assignee_email` | Email of the agent assigned to the ticket |
-
-## Dashboard Capabilities
-
-The pre-built SourceMedium dashboard for Customer Support enables you to:
-
-1. **Filter data** by time period, channel, resolution time, and CSAT score
-2. **Monitor key metrics** through time-series visualizations
-3. **Analyze ticket resolution** by channel and time buckets
-4. **Track CSAT performance** and identify trends
-5. **Export data** for further analysis
-
-## Common Use Cases
-
-### For Dashboard Users
-
-1. **Performance Monitoring**: Track customer support team efficiency with resolution time and one-touch resolution metrics
-2. **Channel Analysis**: Identify which support channels have the highest volume and best resolution rates
-3. **Customer Satisfaction**: Monitor CSAT scores across channels and agents
-4. **SLA Compliance**: Track tickets against resolution time targets
-
-### For Data Engineers
-
-1. **Custom Reporting**: Build specialized reports using the underlying fact and dimension tables
-2. **Data Integration**: Join customer support data with other business metrics
-3. **Custom Metrics**: Define and calculate additional KPIs beyond the pre-built dashboard
-4. **Historical Analysis**: Analyze trends and patterns in customer support performance over time
-
-## Data Refresh Schedule
-
-The Gorgias data is updated daily through an automated ETL pipeline. The latest data available will typically represent activity from the previous day.
-
-## Notes & Additional Resources
-
-### Debug Considerations for Engineers
-
-1. Export all Gorgias tickets by creating a Private view with no filters. [Instructions can be found here](https://docs.gorgias.com/en-US/exports-404844)
-2. Compare Ticket IDs available in the Gorgias exported tickets to the Ticket IDs available in the `dim_customer_support_tickets` table.
-
-### Additional Tickets in Warehouse
-
-Due to API limitations tickets that have been fully deleted from the Gorgias platform will still be visible and included in the reporting and fct/dim data models.
-
-### Discrepancies vs. Gorgias internal analytics
-
-You may notice discrepancies for day-over-day and aggregated metrics versus the Source Medium calculated metrics. This is due to the method of aggregation utilized by Gorgias for their in-platform and API-provided analytics. Another factor that may cause discrepancies are user-account timezone settings. This is because Gorgias' in-platform analytics aggregates based on the timezone set for the user viewing them, whereas Source Medium aggregates based on your e-commerce platform native timezone. Gorgias provides excellent documentation and visualizations on how they calculate their analytics figures, which can be [found here](https://docs.gorgias.com/en-US/how-metrics-are-calculated-406747).
-
-
-### Resources
-- [SourceMedium Documentation](https://docs.sourcemed.com/)
-- [Gorgias API Reference](https://developers.gorgias.com/reference/introduction)
-- [BigQuery SQL Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax)
-
----
-
-For any questions about these data models or to request additional features, please contact SourceMedium support in our shared Slack or Google Chat channels.
diff --git a/data-inputs/platform-overviews/hubspot-platform-overview.mdx b/data-inputs/platform-overviews/hubspot-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/impact-platform-overview.mdx b/data-inputs/platform-overviews/impact-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/klaviyo-platform-overview.mdx b/data-inputs/platform-overviews/klaviyo-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/knocommerce-platform-overview.mdx b/data-inputs/platform-overviews/knocommerce-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/littledata-platform-overview.mdx b/data-inputs/platform-overviews/littledata-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/loop-platform-overview.mdx b/data-inputs/platform-overviews/loop-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/mailchimp-platform-overview.mdx b/data-inputs/platform-overviews/mailchimp-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/meta-platform-overview.mdx b/data-inputs/platform-overviews/meta-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/outbrain-platform-overview.mdx b/data-inputs/platform-overviews/outbrain-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/pepperjam-platform-overview.mdx b/data-inputs/platform-overviews/pepperjam-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/pinterest-platform-overview.mdx b/data-inputs/platform-overviews/pinterest-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/platform-overview-template.mdx b/data-inputs/platform-overviews/platform-overview-template.mdx
deleted file mode 100644
index cec2df7..0000000
--- a/data-inputs/platform-overviews/platform-overview-template.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: 'Platform Overview - {Platform}'
-sidebarTitle: '{Platform} Overview (Template)'
-description: What data is available from SourceMedium's Platform integration?
-icon: 'database'
----
-
-### What `{Platform}` data is available in SourceMedium?
-
-Provide a high-level overview -- 2-4 sentences about the data we report on from the platform and how we use it. Why should the customer integrate this data source?
-- what type of data are we getting, how do we use it (high-level)
-- do we use this data as source of truth for any common concepts
- - e.g. orders, subscriber/subscription stats, marketing spend etc
-
-
-Embed / link out to metric & dimension docs
-
-
-
-1-4 high-level sentences summarizing how this data enriches other data points (e.g. GA4/Elevar etc enriches orders data) and/or is enriched by other data (Shopify orders are enriched by lots of things: ga4, channel mapping, costs, subscription metadata) in our ecosystem.
-
-
-
-- are there optional use cases you can enable with this data that don't come ootb
- - e.g. using discount codes from Shopify orders to populate the Influnecers Deep Dive module
-
-
-
-- are there any confiugrable ways that customers can transform this data
- - either by request (e.g. exclude $0 orders, campaign naming conventions)
- - or self-serve (e.g. channel mapping, influencers deep dive, various costs for ecomm data)
-
-
-### Where is `{Platform}` data surfaced in SourceMedium?
-**Transformed `{Platform}` data is surfaced to the following modules by default**
-- `[Module Name]({link out ot specific module overview in SMU})`
- - high-level of what data is available (don't need to go into all specific fields, but can call out exampels e.g. GA4 data used in Orders Deep Dive `source/medium`)
-- etc.
-
-
-- `[table_name]({link out to specific table docs})`
-- etc.
-
-
-
-### Additional information
-**Data Freshness:**
-SourceMedium attempts to ingest data from the `{Platform}` API every X hours, and fully transformed data should be available within data tables & dashboards within X hrs.
-
-**Default filtering & exclusions `[optional]`**
-
-- e.g. using attr. window set in platform settings for most marketing plats, using strictly 7d click attr. window for FB Ads, e.g. excluding gift card revenue (deferred revenue) for Shopify
-
-**Other data clarifications: data nuances & good-to-knows**
-
-
-
-
-
-
- - vs platform native reporting
- - vs other modules / tables in SM
-
-
-
diff --git a/data-inputs/platform-overviews/recharge-platform-overview.mdx b/data-inputs/platform-overviews/recharge-platform-overview.mdx
deleted file mode 100644
index bfc3dea..0000000
--- a/data-inputs/platform-overviews/recharge-platform-overview.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: 'ReCharge - Platform Overview'
-sidebarTitle: 'Platform Overview'
-description: 'Information on data availability, ingestion, cleaning & transformation, data enrichment and additional use-cases & capabilities'
-icon: 'database'
----
-
-blah blah blah
\ No newline at end of file
diff --git a/data-inputs/platform-overviews/shareasale-platform-overview.mdx b/data-inputs/platform-overviews/shareasale-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/shopify-platform-overview.mdx b/data-inputs/platform-overviews/shopify-platform-overview.mdx
deleted file mode 100644
index d6ef249..0000000
--- a/data-inputs/platform-overviews/shopify-platform-overview.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: 'Shopify - Platform Overview'
-sidebarTitle: 'Platform Overview'
-description: 'Information on data availability, ingestion, cleaning & transformation, data enrichment and additional use-cases & capabilities'
-icon: 'database'
----
-
-### What Shopify data is available in SourceMedium?
-
-As one of the largest & most trusted e-commerce platforms on the market, we consider Shopify data to be
-source-of-truth for a large majority of sales & revenue use cases, and Shopify data is used widely throughout the SourceMedium platform.
-
-SourceMedium ingests & aggregates a myriad of data points from Shopify spanning customer, order, line-item,
-and fulfillment performance (just to name a few)! We aggregate relevant metadata points and tie them back to
-the customers/orders/line-item sales that are driving performance to build a more holistic picture of what you're selling,
-who you're selling to, and where they're coming from.
-
-
-Embed / link out to metric & dimension docs
-
-
-
-- SourceMedium considers **revenue from the sale of gift cards** to be deferred revenue, and therefor we do not report on this revenue until the gift card is redeemed.
-
-
-
-In our ecosystem, Shopify data is often enriched with metadata from additional
-integrations. For example...
-- Google Analytics, Elevar, Littledata etc. for added order-level attribution
-- ReCharge, StayAI etc. for additional subscription insights
-
-
-
-`[optional section]`
-- are there optional use cases you can enable with this data that don't come ootb
- - e.g. using discount codes from Shopify orders to populate the Influnecers Deep Dive module
-
-
-
-`[optional section]`
-- are there any confiugrable ways that customers can transform this data
- - either by request (e.g. exclude $0 orders, campaign naming conventions)
- - or self-serve (e.g. channel mapping, influencers deep dive, various costs for ecomm data)
-
-
-### Where is Shopify data surfaced in SourceMedium?
-**Transformed Shopify data is surfaced to the following modules by default**
-- `[Module Name]({link out ot specific module overview in SMU})`
- - high-level of what data is available (don't need to go into all specific fields, but can call out exampels e.g. GA4 data used in Orders Deep Dive `source/medium`)
-- etc.
-
-
-- `[table_name]({link out to specific table docs})`
-- etc.
-
-
-
-### Data cleaning & transformation notes
-- high-level of aggregations and different types of data we transform/use from this platform
- - do we enrich this data with any other data or alter it in any way before reporting it in dashboards (before it reaches the final tables)
- - e.g. Shopify orders receive UTM enrichment from GA, Littledata, Elevar etc
-- any freshness notes
- - e.g. for Amazon, data is fresh to the previous 48-72 hrs
-- do we remove or filter anything automatically
- - e.g. we don't report on gift card revenue from Shopify
diff --git a/data-inputs/platform-overviews/snapchat-platform-overview.mdx b/data-inputs/platform-overviews/snapchat-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/stay-ai-platform-overview.mdx b/data-inputs/platform-overviews/stay-ai-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/stripe-platform-overview.mdx b/data-inputs/platform-overviews/stripe-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/taboola-platform-overview.mdx b/data-inputs/platform-overviews/taboola-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/tapcart-platform-overview.mdx b/data-inputs/platform-overviews/tapcart-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/tatari-platform-overview.mdx b/data-inputs/platform-overviews/tatari-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/tiktok-platform-overview.mdx b/data-inputs/platform-overviews/tiktok-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-overviews/twitter-platform-overview.mdx b/data-inputs/platform-overviews/twitter-platform-overview.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/data-inputs/platform-supporting-resources/amazon-ads/amazon-ads-data-nuances-and-limitations.mdx b/data-inputs/platform-supporting-resources/amazon-ads/amazon-ads-data-nuances-and-limitations.mdx
index ce6edb3..26ea9a0 100644
--- a/data-inputs/platform-supporting-resources/amazon-ads/amazon-ads-data-nuances-and-limitations.mdx
+++ b/data-inputs/platform-supporting-resources/amazon-ads/amazon-ads-data-nuances-and-limitations.mdx
@@ -1,5 +1,5 @@
---
-title: 'Data Nuances & Limitations'
+title: "Amazon Ads: Data Nuances & Limitations"
sidebarTitle: 'Data Nuances & Limitations'
description: 'Important context for Amazon Ads data'
icon: 'info'
@@ -68,4 +68,4 @@ Follow the steps below to download the Amazon Ads reports that we aim to replica
as the platform-reported conversions and revenue.
- Note that when generating reports via the Amazon Ads UI, Amazon only reports on 7-day attribution windows for Sponsored Products.
Because of this, when comparing attributed Sponsored Product conversions and revenue between SourceMedium and Amazon Ads, our
- reported conversions and revenue numbers should be higher.
\ No newline at end of file
+ reported conversions and revenue numbers should be higher.
diff --git a/data-inputs/platform-supporting-resources/amazon-seller-central/amazon-sc-data-nuances-and-limitations.mdx b/data-inputs/platform-supporting-resources/amazon-seller-central/amazon-sc-data-nuances-and-limitations.mdx
index 34f5d9a..b5b21a4 100644
--- a/data-inputs/platform-supporting-resources/amazon-seller-central/amazon-sc-data-nuances-and-limitations.mdx
+++ b/data-inputs/platform-supporting-resources/amazon-seller-central/amazon-sc-data-nuances-and-limitations.mdx
@@ -1,5 +1,5 @@
---
-title: 'Data Nuances & Limitations'
+title: "Amazon Seller Central: Data Nuances & Limitations"
sidebarTitle: 'Data Nuances & Limitations'
description: 'Important context for Amazon Seller Central data'
icon: 'info'
@@ -41,4 +41,4 @@ platforms while utilizing Amazon's fulfillment services, are classified under th
Amazon Removal Orders, which represent instances where products are removed from Amazon's fulfillment centers, are automatically
categorized under the "Excluded" channel with a dedicated sales channel name of "Amazon Removal Order." This separation ensures
-that removal orders are clearly distinguished from active sales transactions.
\ No newline at end of file
+that removal orders are clearly distinguished from active sales transactions.
diff --git a/data-inputs/platform-supporting-resources/applovin/applovin-data-nuances-and-limitations.mdx b/data-inputs/platform-supporting-resources/applovin/applovin-data-nuances-and-limitations.mdx
index 6281075..b7daf8f 100644
--- a/data-inputs/platform-supporting-resources/applovin/applovin-data-nuances-and-limitations.mdx
+++ b/data-inputs/platform-supporting-resources/applovin/applovin-data-nuances-and-limitations.mdx
@@ -1,5 +1,5 @@
---
-title: 'Data Nuances & Limitations'
+title: "AppLovin: Data Nuances & Limitations"
sidebarTitle: 'Data Nuances & Limitations'
description: 'Important context for AppLovin data'
icon: 'info'
@@ -19,4 +19,3 @@ be attributed to the next day.
Currently, the data that SourceMedium receives via the API is using this concept of the "UTC Day" and will directly match
the report you can see in AppLovin's UI.
-
diff --git a/data-inputs/platform-supporting-resources/ga4/google-analytics-common-failures.mdx b/data-inputs/platform-supporting-resources/ga4/google-analytics-common-failures.mdx
index c0ac047..7679e04 100644
--- a/data-inputs/platform-supporting-resources/ga4/google-analytics-common-failures.mdx
+++ b/data-inputs/platform-supporting-resources/ga4/google-analytics-common-failures.mdx
@@ -26,9 +26,9 @@ Google Analytics has some common failure points that can cause data sources to d
be circumvented by customers.
- Faulty Tracking
- There's no absolute right or wrong approach for setting up UTMs, but most companies make some sort of mistake when setting up tracking.
- The best practices we have identified are covered in this [starter doc](https://www.notion.so/How-can-I-improve-my-last-click-UTM-attribution-0a6796ff8de54b1498aeb7643cbfa0bd?pvs=21) and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
+ The best practices we have identified are covered in [UTM Setup](/help-center/core-concepts/attribution/utm-setup), [Improving Last-Click Attribution](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution), and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
- Factors not visible to SourceMedium
- Tracking is complex, and many other factors that are not visible to SourceMedium can come into play. It is generally reasonable to expect
10-20% discrepancies between Shopify (source of truth) and GA.
-Some of the best practices we have identified are outlined in this [starter doc on improving your last-click attribution](/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution) and our [UTM link-building template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
\ No newline at end of file
+Some of the best practices we have identified are outlined in [UTM Setup](/help-center/core-concepts/attribution/utm-setup), [Improving Last-Click Attribution](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution), and our [UTM link-building template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
diff --git a/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution.mdx b/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution.mdx
index 29a0945..0a563c8 100644
--- a/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution.mdx
+++ b/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution.mdx
@@ -4,6 +4,12 @@ description: 'Follow this guide for tips & tricks on improving your last-click U
icon: 'info'
---
+
+This page duplicates content with the Help Center article: [How can I improve my last-click UTM attribution?](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution)
+
+
+For the canonical “what is a UTM / how do I tag links” guide, see: [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+
### Requirements
Tracking set up through Google Analytics and/or Shopify.
@@ -27,7 +33,7 @@ converting from!
### Steps
1. Check to see that UTMs are applied to all relevant marketing campaigns where links are distributed, from Meta, Google, TikTok, to Influencers & Affiliates
-2. Streamline proper naming conventions for UTMs using our best practices [[click HERE for our shareable template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0)]
+2. Streamline proper naming conventions for UTMs using our best practices ([click HERE for our shareable template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0))
3. Watch out for direct/none UTM tracking, which is a sign that your data and website setup may need fine tuning (ask the team about our *data and analytics audit* where we help to diagnose common pitfalls with tracking.)
### Additional Information
@@ -36,4 +42,4 @@ converting from!
- Changing UTMs of successful marketing campaigns on major channels such as Meta and Google can have a material impact on performance — reach out to the SourceMedium team to learn more about the risks with changing your UTMs
- Pairing zero party data with lack-click UTM attribution can be a powerful combination — ask our team about our advanced `Zero Party Data Module`
-For additional guidance on UTM best practices, check out our [UTM link-building template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
\ No newline at end of file
+For additional guidance on UTM best practices, check out our [UTM link-building template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
diff --git a/data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations.mdx b/data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations.mdx
index fad9e5f..a118353 100644
--- a/data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations.mdx
+++ b/data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations.mdx
@@ -1,5 +1,5 @@
---
-title: 'Data Nuances & Limitations'
+title: "Klaviyo: Data Nuances & Limitations"
sidebarTitle: 'Data Nuances & Limitations'
description: 'Important context for Klaviyo data'
icon: 'info'
@@ -13,4 +13,4 @@ not the send date of a campaign or flow. For this reason, comparing this data wi
is not recommended, as in-app performance is calculated based on send date.
For example, if you ran an email campaign on January 1st and you want to view the unique number of email clicks for
-that campaign from January 1st to January 7th, clicks that happened on January 10th would be included in the in-app Klaviyo metrics but not in the data from the API we use. To see the clicks from January 10th in our data, you would need to expand your time range to include January 10th.
\ No newline at end of file
+that campaign from January 1st to January 7th, clicks that happened on January 10th would be included in the in-app Klaviyo metrics but not in the data from the API we use. To see the clicks from January 10th in our data, you would need to expand your time range to include January 10th.
diff --git a/data-inputs/platform-supporting-resources/shopify/backfilling-utm-attribution-via-checkout-attributes.mdx b/data-inputs/platform-supporting-resources/shopify/backfilling-utm-attribution-via-checkout-attributes.mdx
new file mode 100644
index 0000000..2443362
--- /dev/null
+++ b/data-inputs/platform-supporting-resources/shopify/backfilling-utm-attribution-via-checkout-attributes.mdx
@@ -0,0 +1,580 @@
+---
+title: "Capturing & Backfilling UTM Attribution via Order Attributes"
+sidebarTitle: "Capturing & Backfilling Attribution"
+description: 'How to backfill historical orders with UTM attribution data and capture UTMs for future orders'
+icon: 'code'
+---
+
+
+**Audience**: This guide is for developers and technical teams who need to add UTM attribution data to Shopify orders—either backfilling historical orders or capturing UTMs for future orders.
+
+
+## Overview
+
+SourceMedium extracts UTM attribution data from Shopify order-level `customAttributes`. This guide covers two scenarios:
+
+1. **Backfilling existing orders** — You have attribution data (from spreadsheets, surveys, external tools) and want to write it to historical orders.
+2. **Capturing UTMs going forward** — You want to automatically capture UTM parameters at checkout for future orders.
+
+
+
+ Use the Shopify Admin API to add attribution data to existing orders
+
+
+ Use Checkout UI Extensions to automatically capture UTMs at checkout
+
+
+
+---
+
+## Supported Keys (Normalized)
+
+SourceMedium extracts a specific allowlist of keys from order-level `customAttributes`.
+
+Keys are **normalized** before matching (snake_case / camelCase / delimiter / case agnostic):
+- `utm_source`, `utmSource`, `UTM_SOURCE`, `utm-source` → treated as the same key
+- `sm_utmParams`, `smUtmParams` → treated as the same key
+- `GE_utmParams`, `ge_utm_params` → treated as the same key
+
+
+To reduce collisions with other checkout apps, prefer the `sm_utm_*` / `sm_utmParams` keys for explicit overrides. Standard `utm_*` keys are also supported.
+
+
+| Key | Description | Example |
+|-----|-------------|---------|
+| `sm_utm_source`, `sm_utm_medium`, `sm_utm_campaign`, `sm_utm_content`, `sm_utm_term`, `sm_utm_id` | SourceMedium override UTMs (recommended) | `sm_utm_source=facebook` |
+| `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id` | Standard UTMs | `utm_campaign=summer_sale_2025` |
+| `sm_utmParams`, `utmParams`, `GE_utmParams` | Aggregate UTM query string (parsed) | `utm_source=google&utm_medium=cpc` |
+| `sm_referrer`, `referrer` | Referring URL | `https://blog.example.com/review` |
+
+### Click IDs (fallback inference)
+
+Click IDs are processed but **not stored as raw values**. If no explicit `utm_source` is present, their presence infers a channel-level `utm_source` (fallback-only).
+
+| Click ID | Inferred `utm_source` |
+|----------|------------------------|
+| `scclid` | `snapchat` |
+| `irclickid` | `impact` |
+| `msclkid` | `microsoft` |
+| `ttclid` | `tiktok` |
+| `fbclid` | `meta` |
+| `gclid` | `google` |
+
+If multiple click IDs exist, the system prioritizes: `scclid` > `irclickid` > `msclkid` > `ttclid` > `fbclid` > `gclid`.
+
+### Conflict resolution (deterministic)
+
+If you provide conflicting values (e.g., both `sm_utm_source` and `utm_source`, or both direct keys and `utmParams`), SourceMedium resolves each final field with a deterministic waterfall:
+
+- **UTM fields**: direct `sm_utm_*` → direct `utm_*` → parsed from `sm_utmParams` → parsed from `utmParams` → parsed from `GE_utmParams`
+- **`utm_source` only**: if still missing, infer from click IDs (`scclid` → `irclickid` → `msclkid` → `ttclid` → `fbclid` → `gclid`)
+- **Referrer**: `sm_referrer` → `referrer`
+
+If the same normalized key appears multiple times at the same level (e.g., `utm_source` and `UTM_SOURCE`), SourceMedium de-dupes deterministically using `MAX()` (lexicographically largest value). To avoid surprises, only set each key once.
+
+---
+
+## Backfilling Historical Orders
+
+If you have attribution data for existing orders (e.g., from post-purchase surveys, manual tracking, or external tools), you can write it to Shopify orders so SourceMedium can extract it.
+
+### How It Works
+
+```mermaid
+flowchart LR
+ A[Your attribution data CSV/spreadsheet/database] --> B[Update orders via API or Shopify Flow]
+ B --> C[customAttributes added to existing orders]
+ C --> D[SourceMedium extracts on next sync]
+ D --> E[Attribution appears in dashboards]
+```
+
+### Available Methods
+
+| Method | Best For | Technical Skill Required |
+|--------|----------|--------------------------|
+| **Shopify Flow** | Small batches, no-code users, Shopify Plus | Low (no coding) |
+| **Admin API Script** | Large bulk backfills, automation | Medium (Python/Node.js) |
+| **Third-Party Apps** | Limited - most don't support order attributes | Varies |
+
+
+**No CSV import available**: Unlike products, Shopify does not support CSV import for order attributes. Matrixify and similar bulk import tools also do not support `customAttributes` on orders.
+
+
+---
+
+### Option 1: Shopify Flow (No-Code)
+
+If you have Shopify Plus, you can use **Shopify Flow** with the "Send Admin API request" action. This is ideal for smaller batches or when you want to trigger updates based on conditions.
+
+
+
+ Go to **Settings → Flow** and create a new workflow. Use a trigger like "Order created" for new orders, or tag orders you want to backfill and trigger on "Order tags added".
+
+
+ Select **GraphQL Admin API** and choose the **orderUpdate** mutation.
+
+
+ Use this template to preserve existing attributes while adding new ones:
+
+ **Mutation:**
+ ```graphql
+ mutation orderUpdate($input: OrderInput!) {
+ orderUpdate(input: $input) {
+ order { id }
+ userErrors { field message }
+ }
+ }
+ ```
+
+ **Variables (JSON with Liquid):**
+ ```liquid
+ {
+ "input": {
+ "id": "{{ order.id }}",
+ "customAttributes": [
+ {%- for attr in order.customAttributes -%}
+ { "key": "{{ attr.key }}", "value": "{{ attr.value }}" }{% unless forloop.last %},{% endunless %}
+ {%- endfor -%},
+ { "key": "sm_utm_source", "value": "facebook" },
+ { "key": "sm_utm_medium", "value": "cpc" }
+ ]
+ }
+ }
+ ```
+
+
+
+
+The `orderUpdate` mutation **replaces all** `customAttributes`. The Liquid loop above preserves existing attributes—don't skip it or you'll lose data.
+
+
+---
+
+### Option 2: Admin API Script (Bulk)
+
+For large backfills (hundreds or thousands of orders), use a script with the [Shopify Admin GraphQL API](https://shopify.dev/docs/api/admin-graphql/latest/mutations/orderUpdate).
+
+#### Prerequisites
+
+Shopify Admin API access with `write_orders` scope
+Order IDs mapped to your attribution data
+Attribution data in the supported key format (see table above)
+
+#### Implementation
+
+
+
+ ```graphql
+ mutation orderUpdate($input: OrderInput!) {
+ orderUpdate(input: $input) {
+ order {
+ id
+ customAttributes {
+ key
+ value
+ }
+ }
+ userErrors {
+ field
+ message
+ }
+ }
+ }
+ ```
+
+ **Variables:**
+ ```json
+ {
+ "input": {
+ "id": "gid://shopify/Order/1234567890",
+ "customAttributes": [
+ { "key": "sm_utm_source", "value": "facebook" },
+ { "key": "sm_utm_medium", "value": "cpc" },
+ { "key": "sm_utm_campaign", "value": "summer_sale_2025" }
+ ]
+ }
+ }
+ ```
+
+
+ ```python
+ import shopify
+ import csv
+
+ # Initialize Shopify session
+ shop_url = "your-store.myshopify.com"
+ api_version = "2024-10"
+ access_token = "your-access-token"
+
+ session = shopify.Session(shop_url, api_version, access_token)
+ shopify.ShopifyResource.activate_session(session)
+
+ def backfill_order_attribution(order_id: str, attribution: dict):
+ """
+ Update an order with UTM attribution data.
+
+ Args:
+ order_id: Shopify order ID (numeric, e.g., "1234567890")
+ attribution: Dict with keys like utm_source, utm_medium, etc.
+ """
+ # Build customAttributes array
+ custom_attributes = [
+ {"key": key, "value": value}
+ for key, value in attribution.items()
+ if value # Skip empty values
+ ]
+
+ # GraphQL mutation
+ query = """
+ mutation orderUpdate($input: OrderInput!) {
+ orderUpdate(input: $input) {
+ order {
+ id
+ customAttributes { key value }
+ }
+ userErrors { field message }
+ }
+ }
+ """
+
+ variables = {
+ "input": {
+ "id": f"gid://shopify/Order/{order_id}",
+ "customAttributes": custom_attributes
+ }
+ }
+
+ result = shopify.GraphQL().execute(query, variables)
+ return result
+
+ # Example: Backfill from CSV
+ with open('attribution_data.csv', 'r') as f:
+ reader = csv.DictReader(f)
+ for row in reader:
+ order_id = row['order_id']
+ attribution = {
+ 'utm_source': row.get('source', ''),
+ 'utm_medium': row.get('medium', ''),
+ 'utm_campaign': row.get('campaign', ''),
+ }
+
+ result = backfill_order_attribution(order_id, attribution)
+ print(f"Updated order {order_id}: {result}")
+ ```
+
+
+ ```javascript
+ import '@shopify/shopify-api/adapters/node';
+ import { shopifyApi } from '@shopify/shopify-api';
+
+ const shopify = shopifyApi({
+ apiKey: process.env.SHOPIFY_API_KEY,
+ apiSecretKey: process.env.SHOPIFY_API_SECRET,
+ scopes: ['write_orders'],
+ hostName: 'your-store.myshopify.com',
+ apiVersion: '2024-10',
+ });
+
+ async function backfillOrderAttribution(session, orderId, attribution) {
+ const client = new shopify.clients.Graphql({ session });
+
+ const customAttributes = Object.entries(attribution)
+ .filter(([_, value]) => value) // Skip empty values
+ .map(([key, value]) => ({ key, value }));
+
+ const response = await client.request(`
+ mutation orderUpdate($input: OrderInput!) {
+ orderUpdate(input: $input) {
+ order {
+ id
+ customAttributes { key value }
+ }
+ userErrors { field message }
+ }
+ }
+ `, {
+ variables: {
+ input: {
+ id: `gid://shopify/Order/${orderId}`,
+ customAttributes,
+ },
+ },
+ });
+
+ return response;
+ }
+
+ // Example usage
+ const attribution = {
+ utm_source: 'facebook',
+ utm_medium: 'cpc',
+ utm_campaign: 'summer_sale_2025',
+ };
+
+ await backfillOrderAttribution(session, '1234567890', attribution);
+ ```
+
+
+
+### Important Considerations
+
+
+
+ The `orderUpdate` mutation **replaces** all `customAttributes` on the order. If the order already has attributes you want to keep:
+
+ 1. First, fetch existing attributes via `order` query
+ 2. Merge your new attributes with existing ones
+ 3. Send the combined array in the mutation
+
+ ```python
+ # Fetch existing attributes first
+ existing = get_order_attributes(order_id)
+ merged = {**existing, **new_attribution} # New values overwrite existing
+ backfill_order_attribution(order_id, merged)
+ ```
+
+
+
+ Shopify's Admin API has rate limits. For bulk backfills:
+
+ - Use the [Bulk Operations API](https://shopify.dev/docs/api/admin-graphql/latest/queries/bulkOperationRunQuery) for large datasets
+ - Or throttle requests to ~2 per second for standard API calls
+ - Consider batching updates overnight
+
+
+
+ Shopify allows updating orders regardless of age, but consider:
+
+ - Very old orders may already have SourceMedium attribution from other sources
+ - Order-level `customAttributes` are treated as an explicit override (see [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy))
+
+
+
+### Verification
+
+After backfilling:
+
+1. **Verify in Shopify Admin**: Orders → [Order] → Additional details should show your attributes
+2. **Wait for sync**: SourceMedium syncs typically run every 24 hours
+3. **Check Orders Deep Dive**: Verify the attribution appears in SourceMedium dashboards
+
+---
+
+## Capturing UTMs for Future Orders
+
+To automatically capture UTM parameters at checkout for new orders, use a Shopify Checkout UI Extension.
+
+
+This approach **supplements** your existing tracking (GA4, Elevar). It's particularly useful when cookie-based tracking fails due to ad blockers or cross-domain issues.
+
+
+### How It Works
+
+```mermaid
+flowchart LR
+ A[User lands on site with UTM params] --> B[Storefront writes attribution to cart/checkout attributes]
+ B --> C[Attributes become order customAttributes]
+ C --> D[SourceMedium extracts from order data]
+ D --> E[Attribution appears in dashboards]
+```
+
+### Prerequisites
+
+Shopify Plus or ability to create Checkout UI Extensions
+Access to deploy changes to your Shopify theme/app
+Method to write cart attributes before checkout (theme JS / Storefront API)
+
+### Step 1: Write Attribution to Cart Attributes (Before Checkout)
+
+Checkout UI Extensions are sandboxed and can't directly access the browser DOM (e.g., `document.cookie`, `localStorage`, or `window.location`). To make UTMs available at checkout, capture them on the storefront and write them into **cart attributes** before the buyer starts checkout.
+
+This example uses the Online Store `cart/update` endpoint to set SourceMedium override keys (`sm_utm_*`). These cart attributes flow into checkout attributes and appear on the order as `customAttributes`.
+
+```javascript
+// theme.js (storefront)
+function getParam(name) {
+ return new URLSearchParams(window.location.search).get(name);
+}
+
+const attributes = {
+ sm_utm_source: getParam('utm_source'),
+ sm_utm_medium: getParam('utm_medium'),
+ sm_utm_campaign: getParam('utm_campaign'),
+ sm_utm_content: getParam('utm_content'),
+ sm_utm_term: getParam('utm_term'),
+ sm_utm_id: getParam('utm_id'),
+ // Optional click IDs for fallback inference (not stored as raw values in SourceMedium)
+ scclid: getParam('scclid'),
+ irclickid: getParam('irclickid'),
+ msclkid: getParam('msclkid'),
+ ttclid: getParam('ttclid'),
+ fbclid: getParam('fbclid'),
+ gclid: getParam('gclid'),
+ sm_referrer: document.referrer || null,
+};
+
+const cleanAttributes = Object.fromEntries(
+ Object.entries(attributes).filter(([_, v]) => v != null && v !== '')
+);
+
+if (Object.keys(cleanAttributes).length > 0) {
+ fetch('/cart/update.js', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ attributes: cleanAttributes }),
+ });
+}
+```
+
+
+Set these attributes **before** the buyer starts checkout. If you update cart attributes after checkout is already open, they might not be reflected unless the buyer refreshes checkout.
+
+
+
+If you're using a headless storefront, use the Storefront API to set cart attributes instead of `cart/update.js`.
+
+
+### Step 2: Create Checkout UI Extension
+
+```typescript
+// extensions/utm-capture/src/Checkout.tsx
+import { useEffect } from 'react';
+import {
+ reactExtension,
+ useApplyAttributeChange,
+ useAttributes,
+} from '@shopify/ui-extensions-react/checkout';
+
+export default reactExtension('purchase.checkout.block.render', () => );
+
+function UtmCapture() {
+ const applyAttributeChange = useApplyAttributeChange();
+ const currentAttributes = useAttributes();
+
+ useEffect(() => {
+ void ensureSmOverrideKeys();
+ }, []);
+
+ function getAttributeValue(key: string): string | null {
+ return currentAttributes.find(attr => attr.key === key)?.value ?? null;
+ }
+
+ async function ensureSmOverrideKeys() {
+ // Checkout UI extensions cannot access cookies or localStorage.
+ // This helper maps any existing `utm_*` attributes to `sm_utm_*` override keys.
+ const mapping: Record = {
+ sm_utm_source: getAttributeValue('sm_utm_source') ?? getAttributeValue('utm_source'),
+ sm_utm_medium: getAttributeValue('sm_utm_medium') ?? getAttributeValue('utm_medium'),
+ sm_utm_campaign: getAttributeValue('sm_utm_campaign') ?? getAttributeValue('utm_campaign'),
+ sm_utm_content: getAttributeValue('sm_utm_content') ?? getAttributeValue('utm_content'),
+ sm_utm_term: getAttributeValue('sm_utm_term') ?? getAttributeValue('utm_term'),
+ sm_utm_id: getAttributeValue('sm_utm_id') ?? getAttributeValue('utm_id'),
+ };
+
+ for (const [key, value] of Object.entries(mapping)) {
+ if (!value) continue;
+
+ const existing = currentAttributes.find(attr => attr.key === key);
+ if (existing) continue;
+
+ try {
+ await applyAttributeChange({ type: 'updateAttribute', key, value });
+ } catch (err) {
+ // Silently fail - accelerated checkout will throw
+ console.debug(`[UTM Capture] Error setting ${key}:`, err);
+ }
+ }
+ }
+
+ return null;
+}
+```
+
+### Step 3: Configure and Deploy
+
+```toml
+# extensions/utm-capture/shopify.extension.toml
+api_version = "2024-10"
+
+[[extensions]]
+type = "ui_extension"
+name = "UTM Attribution Capture"
+handle = "utm-capture"
+
+[[extensions.targeting]]
+module = "./src/Checkout.tsx"
+target = "purchase.checkout.block.render"
+```
+
+```bash
+shopify app deploy
+```
+
+### Limitations
+
+
+**Accelerated Checkout**: The `applyAttributeChange()` method fails for Apple Pay, Google Pay, and Shop Pay express checkouts. This typically affects 10-30% of orders. Use this as a supplement to GA4/Elevar, not a replacement.
+
+
+---
+
+## Troubleshooting
+
+
+
+ 1. **Unsupported key**: Only allowlisted keys are extracted (see "Supported Keys")
+ 2. **Sync timing**: Wait 24-48 hours for data to flow through
+ 3. **Connector version**: Ensure your Shopify connector supports `customAttributes` (contact support to verify)
+
+
+
+ Ensure your API credentials have `write_orders` scope. For private apps, this must be enabled in the app settings.
+
+
+
+ The `orderUpdate` mutation replaces all attributes. Fetch existing attributes first, merge, then update.
+
+
+
+---
+
+## Related Resources
+
+
+
+ Official documentation for the orderUpdate mutation
+
+
+ Documentation for useApplyAttributeChange hook
+
+
+ What UTMs are, what each value means, and how to tag links
+
+
+ How SourceMedium prioritizes attribution from multiple sources
+
+
+
+---
+
+## FAQ
+
+
+
+ - **Backfill**: You have historical attribution data you want to add to existing orders
+ - **Capture going forward**: You want to automatically capture UTMs for new orders
+ - **Both**: Most brands benefit from backfilling historical data AND capturing future UTMs
+
+
+
+ SourceMedium uses an [attribution source hierarchy](/data-transformations/attribution-source-hierarchy). If allowlisted attribution is present in order `customAttributes`, it is treated as an explicit override and takes top priority.
+
+
+
+ Yes. If you write allowlisted attribution to order `customAttributes`, it is treated as an explicit override and will replace the order's last-touch attribution (unless you only set a subset of fields, in which case missing fields may be filled from lower-priority sources when the channel matches).
+
+
+
+ SourceMedium's latest Shopify connector extracts `customAttributes` automatically. Contact support if you're unsure whether your connector supports this feature.
+
+
diff --git a/data-transformations/attribution-source-hierarchy.mdx b/data-transformations/attribution-source-hierarchy.mdx
new file mode 100644
index 0000000..8a4dc40
--- /dev/null
+++ b/data-transformations/attribution-source-hierarchy.mdx
@@ -0,0 +1,272 @@
+---
+title: "Attribution Source Hierarchy"
+description: "How SourceMedium decides which UTM data source wins when multiple systems capture attribution for an order"
+icon: "layer-group"
+---
+
+When SourceMedium receives an order, we often have attribution data from multiple first-party inputs, including Shopify visits, order custom attributes, website events, and Google Analytics transaction data.
+
+The **Attribution Source Hierarchy** is our **Resolution Strategy**. It determines how we intelligently resolve conflicts when data is available from multiple places, ensuring we always use the most granular and reliable signal available for every single order.
+
+
+This is a **last-click (UTM-based) attribution** system. We prioritize data sources that capture the customer's most recent measurable marketing touch before purchase.
+
+
+## Primary Attribution Source Hierarchy
+
+The order attribution system evaluates data sources in this specific priority order:
+
+| Priority | Source Type | Description |
+|----------|-------------|-------------|
+| 1 | Shopify Custom Attributes Override | Order-level attribution set via Shopify `customAttributes` (Checkout / Admin GraphQL API). Treated as an explicit override (`shopify_custom_attribute_override`). |
+| 2 | Shopify Last Customer Visit | The final tracked visit before order placement, captured by Shopify's customer visit tracking |
+| 3 | Shopify Landing Site | UTM parameters extracted from the order's landing page URL |
+| 4 | Shopify Order Notes (Legacy) | UTM data written to order notes / note attributes by tracking tools (Elevar, Blotout, etc.) |
+| 5 | Website Event Tracking | First-party event pixels from GA4, Elevar, or other website analytics |
+| 6 | Shopify First Customer Visit | The customer's first tracked visit, captured by Shopify's customer visit tracking |
+| 7 | Google Analytics (GA4 primary) | Transaction data tied from Google Analytics. GA4 is the primary ongoing source; retained UA exports are treated as historical-only if present. |
+| 8 | Shopify Order Referring Site UTMs | UTM parameters parsed from the order's `referring_site` URL |
+
+If data is missing at priority 1, the system "falls" to priority 2, and so on until it finds valid UTM data.
+
+
+Final source ranking is deterministic and tenant-scoped at the order level.
+
+
+```mermaid
+flowchart TB
+ A[1. Shopify customAttributes override] --> B[2. Shopify last customer visit]
+ B --> C[3. Shopify landing site]
+ C --> D[4. Shopify order notes (legacy)]
+ D --> E[5. Website event tracking]
+ E --> F[6. Shopify first customer visit]
+ F --> G[7. GA4]
+ G --> H[8. Shopify referring_site UTMs]
+```
+
+
+Universal Analytics (UA) has been sunset by Google. If your organization already exported and retained historical UA data, treat it as historical-only and prefer GA4 for ongoing tracking.
+
+
+
+**Why does "Last Customer Visit" beat "First Customer Visit"?**
+
+Because we're building a last-click attribution model. The most recent touchpoint before purchase (last visit) is more relevant for understanding what drove the conversion than the first touchpoint (which may have been weeks earlier).
+
+
+## Google Analytics Transaction Tie Rules (Priority 7)
+
+Google Analytics transaction records are considered tie-eligible for order matching when the transaction ID can be safely parsed into an order-like numeric key using the following logic:
+
+1. `transaction_id` matches `^#[0-9]{4,}$` (for example `#6589`), or
+2. `transaction_id` has a trailing numeric suffix with length `>= 5`.
+
+Short non-hashtag numeric IDs remain blocked to reduce accidental collisions.
+
+For a valid tie, the transaction-to-order window is bounded to **-1..90 days** relative to the order processed date. If a valid tie exists, this source participates at priority 7 in the hierarchy.
+
+## Website Event Tracking Details
+
+For website event tracking sources (priority 5), the system uses qualifying events in a **0..90 day window** relative to the order.
+
+When multiple events exist, they're ranked by:
+1. Days between event and order (closer to order = higher priority)
+2. Event timestamp (earlier `event_local_datetime` wins ties)
+3. Event ID and source system (as final tie-breakers)
+
+If a website event has a UTM source, that's used directly. If only a referrer domain is available, the source is inferred from the domain and the medium defaults to `referral`.
+
+## Shopify Custom Attributes Override (Priority 1)
+
+If your Shopify order has attribution data written to `customAttributes` (Shopify Admin GraphQL API / Checkout attributes), SourceMedium treats it as an **explicit override** and prioritizes it ahead of the default Shopify attribution sources (visits, landing site, website events, GA4).
+
+This is the recommended mechanism for:
+- Backfilling attribution onto historical orders
+- Capturing UTMs at checkout when cookie-based tracking is unreliable (ad blockers, ITP, cross-domain, etc.)
+
+### Supported keys (allowlist)
+
+Only a specific set of keys are extracted from `customAttributes` to prevent accidental capture of non-attribution data.
+
+Keys are **normalized** (case + delimiter + snake/camel agnostic) before matching:
+- `utm_source`, `utmSource`, `UTM_SOURCE`, `utm-source` → treated as the same key
+- `sm_utmParams`, `smUtmParams` → treated as the same key
+- `GE_utmParams`, `ge_utm_params` → treated as the same key
+
+| Key | Purpose |
+|-----|---------|
+| `sm_utm_source`, `sm_utm_medium`, `sm_utm_campaign`, `sm_utm_content`, `sm_utm_term`, `sm_utm_id` | SourceMedium override keys (recommended to avoid collisions with other apps) |
+| `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id` | Standard UTM keys |
+| `sm_utmParams`, `utmParams`, `GE_utmParams` | Aggregate UTM query-string fields (parsed into individual UTM keys) |
+| `sm_referrer`, `referrer` | Referring URL |
+
+### Conflict resolution (deterministic)
+
+If your `customAttributes` data is messy (duplicate keys, multiple sources provided), SourceMedium applies a deterministic waterfall to resolve each final field.
+
+#### Field-level precedence
+
+For each UTM field, the **first non-empty value wins** (highest → lowest):
+
+1. Direct SM override key (`sm_utm_*`)
+2. Direct standard UTM key (`utm_*`)
+3. Parsed from `sm_utmParams` (query string)
+4. Parsed from `utmParams` (query string)
+5. Parsed from `GE_utmParams` (query string)
+6. **`utm_source` only**: click ID inference (`scclid` → `irclickid` → `msclkid` → `ttclid` → `fbclid` → `gclid`)
+
+`referrer` is resolved similarly: `sm_referrer` → `referrer`.
+
+#### Duplicate keys (same tier)
+
+If the same normalized key appears multiple times at the same tier (for example both `utm_source` and `UTM_SOURCE`, or repeated `utm_source` entries), SourceMedium de-dupes deterministically using `MAX()` (lexicographically largest value after decoding/cleaning).
+
+To avoid surprises, only set each key once.
+
+
+Click IDs are processed as a **fallback** (see below), but the raw click ID values are not stored as attribution fields.
+
+
+### Aggregate UTM fields
+
+If you send `sm_utmParams`, `utmParams`, or `GE_utmParams` as a URL query string (e.g., `utm_source=google&utm_medium=cpc`), SourceMedium parses it and extracts the individual UTM keys. Parsing is snake/camel agnostic (both `utm_source=` and `utmSource=` are supported) and URL-decoding is applied.
+
+#### URL Handling
+
+URL encoding in `sm_utmParams`, `utmParams`, and `GE_utmParams` values is fully decoded:
+- Percent encoding: `%XX` patterns (e.g., `%20` → space, `%26` → `&`)
+- Form-style encoding: `+` characters are decoded as spaces (common in checkout apps)
+
+### Click ID to Channel Inference
+
+When only a click ID is present (no explicit `utm_source`), the system infers a fallback `utm_source` value:
+
+| Priority (highest first) | Click ID | Inferred `utm_source` | Platform |
+|--------------------------|----------|------------------------|----------|
+| 1 | `scclid` | snapchat | Snapchat Ads |
+| 2 | `irclickid` | impact | Impact (Affiliate) |
+| 3 | `msclkid` | microsoft | Microsoft/Bing Ads |
+| 4 | `ttclid` | tiktok | TikTok Ads |
+| 5 | `fbclid` | meta | Meta (Facebook/Instagram) |
+| 6 | `gclid` | google | Google Ads |
+
+If an order has multiple click IDs, the highest-priority click ID wins. This preserves more specific intent signals (like affiliates or smaller platforms) over ambient IDs from high-volume platforms.
+
+Click IDs are checked in this order:
+1. Direct `customAttributes` click ID keys (e.g., `scclid`, `gclid`)
+2. Click IDs embedded inside `utmParams`
+3. Click IDs embedded inside `GE_utmParams`
+
+
+Click IDs are **fallback only**. If an explicit `utm_source` exists, it takes precedence over any click ID inference.
+
+
+### Checkout UI Extensions (recommended)
+
+Use Shopify Checkout UI Extensions to write attribution to checkout attributes (which become order `customAttributes`).
+
+```typescript
+import { useEffect } from 'react';
+import { reactExtension, useApplyAttributeChange, useAttributes } from '@shopify/ui-extensions-react/checkout';
+
+export default reactExtension('purchase.checkout.block.render', () => );
+
+function AttributionCapture() {
+ const applyAttributeChange = useApplyAttributeChange();
+ const attributes = useAttributes();
+
+ useEffect(() => {
+ void setAttribution();
+ }, []);
+
+ function getAttributeValue(key: string): string | null {
+ return attributes.find(attr => attr.key === key)?.value ?? null;
+ }
+
+ async function setAttribution() {
+ const attribution = {
+ // Prefer explicit SM overrides if present; otherwise map from standard UTM attributes.
+ sm_utm_source: getAttributeValue('sm_utm_source') ?? getAttributeValue('utm_source'),
+ sm_utm_medium: getAttributeValue('sm_utm_medium') ?? getAttributeValue('utm_medium'),
+ sm_utm_campaign: getAttributeValue('sm_utm_campaign') ?? getAttributeValue('utm_campaign'),
+ sm_utm_content: getAttributeValue('sm_utm_content') ?? getAttributeValue('utm_content'),
+ sm_utm_term: getAttributeValue('sm_utm_term') ?? getAttributeValue('utm_term'),
+ sm_utm_id: getAttributeValue('sm_utm_id') ?? getAttributeValue('utm_id'),
+ };
+
+ for (const [key, value] of Object.entries(attribution)) {
+ if (!value) continue;
+
+ const result = await applyAttributeChange({
+ type: 'updateAttribute',
+ key,
+ value: String(value),
+ });
+
+ if (result.type === 'error') {
+ console.error('Failed to set attribution:', result.message);
+ }
+ }
+ }
+
+ return null;
+}
+```
+
+
+Accelerated checkout methods (Apple Pay, Google Pay, Shop Pay express) may bypass checkout extension execution. Use this as a supplement to GA4/server-side tracking, not a single point of failure.
+
+
+
+Checkout UI extensions are sandboxed and can't access the browser DOM (e.g., `document.cookie`, `localStorage`, or `window.location`). Capture UTMs on the storefront and write them into cart/checkout attributes before checkout starts.
+
+
+
+Custom attributes may be used by other apps. To reduce collisions, prefer `sm_utm_*` / `sm_utmParams` keys for explicit overrides (matching is normalized, but canonical keys reduce ambiguity).
+
+
+## Shopify Order Notes (Priority 4)
+
+Order notes are a key attribution source written by server-side tracking tools like **Elevar** and **Blotout**. These tools capture UTMs at checkout and write them to Shopify order notes / note attributes.
+
+
+If you have control over implementation, prefer **customAttributes override (priority 1)** instead of writing attribution into notes. Notes are shared and can be overwritten by apps; custom attributes are clearer and explicitly prioritized.
+
+
+### Note Attributes (Legacy)
+
+The system supports extracting attribution from legacy `note_attributes` patterns, including:
+- Standard UTM keys like `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id`
+- Tool-specific payloads (e.g., `_elevar_visitor_info`) when they contain nested UTM data
+
+## UTM Field Collapsing
+
+After the primary source is determined, the system "collapses" supplementary UTM fields from lower-priority sources.
+
+**Example:** If priority 2 (Last Customer Visit) provides `utm_source=google` but no `utm_campaign`, and priority 3 (Landing Site) has `utm_campaign=summer_sale`, the final attribution will combine:
+- `utm_source=google` (from priority 2)
+- `utm_campaign=summer_sale` (from priority 3)
+
+This only happens when the `utm_source` grouped channel is the **same** across sources—we don't mix data from different channels.
+
+## Implementation Notes (Advanced)
+
+- For Shopify order notes, if note-level `utm_source` is missing, note `channel` may be used as a fallback source value.
+- Final `sm_utm_*` fields can be completed by downstream override logic when hierarchy output is null or direct/non-actionable.
+
+## Related Resources
+
+
+
+ Overview of last-click vs. multi-touch attribution
+
+
+ Tips for improving UTM tracking quality
+
+
+ How we enrich and standardize your data
+
+
+ Check and improve your attribution data quality
+
+
diff --git a/data-transformations/data-cleaning.mdx b/data-transformations/data-cleaning.mdx
index 5357416..485a749 100644
--- a/data-transformations/data-cleaning.mdx
+++ b/data-transformations/data-cleaning.mdx
@@ -1,7 +1,7 @@
---
title: 'Data Cleaning'
description: 'The first mile of our data transformation process'
-icon: ''
+icon: "gear"
---
## How We Deliver Clean Data
@@ -36,4 +36,4 @@ in ET, creating unexpected data quality issues.
### Lowercasing Inconsistent Values
For textual data, especially computer-generated values, standardizing capitalization conventions by converting all entries to lowercase can
reduce complexity and improve data uniformity. This method is particularly useful for data fields that are prone to inconsistent capitalization,
-ensuring that comparisons and searches are not case-sensitive and more reliable.
\ No newline at end of file
+ensuring that comparisons and searches are not case-sensitive and more reliable.
diff --git a/data-transformations/data-enrichment.mdx b/data-transformations/data-enrichment.mdx
index ebf3afb..8e98caa 100644
--- a/data-transformations/data-enrichment.mdx
+++ b/data-transformations/data-enrichment.mdx
@@ -1,7 +1,7 @@
---
title: 'Data Enrichment'
description: 'The next mile of our data transformation process'
-icon: ''
+icon: "gear"
---
## Augmenting Your Data With Detailed Context
@@ -26,12 +26,23 @@ to enable the creation of custom groupings, termed as sub-channels. This functio
examination of orders, customers, and other entities in your data.
### Last Click UTM Stitching
-We ingest last-click UTM data from an array of sources, including Shopify, website analytics tools, referring domains, zero-party attribution (post-purchase surveys)
-and other event tracking optimization platforms. However, this data is rarely consistent, creating confusion and making it difficult to truly understand
+We ingest last-click UTM data from an array of sources, including Shopify, website analytics tools, referring domains, zero-party attribution (post-purchase surveys)
+and other event tracking optimization platforms. However, this data is rarely consistent, creating confusion and making it difficult to truly understand
the efficacy of your advertising efforts.
-To address this issue, we've developed a model that cleans, standardizes, and aggregates this data into a single table to make it much
+To address this issue, we've developed a model that cleans, standardizes, and aggregates this data into a single table to make it much
easier to work with (for example, to build your own multi-touch attribution analysis).
-While we don't currently offer any media mix modeling solutions in-house, we simplify last-click UTM attribution reporting by using the aforementioned model and
-prioritizing the data we ingest from source-of-truth platforms closer to the actual transaction.
\ No newline at end of file
+While we don't currently offer any media mix modeling solutions in-house, we simplify last-click UTM attribution reporting by using the aforementioned model and
+prioritizing the data we ingest from source-of-truth platforms closer to the actual transaction.
+
+
+For details on how we prioritize between different UTM data sources, see the [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy) documentation.
+
+
+### Customer Demographics
+Demographic attributes like age and gender generally **aren’t available by default** in e-commerce and ad-platform data exports in a way that can be joined to customer LTV.
+
+For practical paths (zero-party collection, third-party enrichment, cautious inference, and what geography we already have), see: [Demographic Data: What You Can (and Can’t) Do](/help-center/core-concepts/demographics/demographic-data-sources).
+
+If you’re trying to understand whether a *targeting strategy* (e.g., “female 25–34” or “new parents”) produces better long-term customers, a common approach is to encode that segment into UTMs so it becomes joinable to purchases. See the “Strategy-based audience segments” section in [Customer Record Enrichment](/help-center/core-concepts/customer-record-enrichment/index).
diff --git a/data-transformations/naming-conventions/boolean-columns.mdx b/data-transformations/naming-conventions/boolean-columns.mdx
index 08cb038..1cd4453 100644
--- a/data-transformations/naming-conventions/boolean-columns.mdx
+++ b/data-transformations/naming-conventions/boolean-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Boolean Columns'
-description: ''
-icon: ''
+description: 'Naming rules for boolean fields (`is_...`) so true/false columns read like a question.'
+icon: "tags"
---
-
### Overview
Boolean columns are named to clearly reflect a true or false condition, and are always phrased in the form of a question.
@@ -18,4 +17,4 @@ that can either be true or false.
- `is_price_tax_inclusive`, where `price` is the `entity` and `tax_inclusive` is the `dimension`
indicating whether the price includes tax
- `is_product_gift_card`, where `product` is the `entity` and `gift_card` is the `dimension`
-indicating whether the product is a gift card
\ No newline at end of file
+indicating whether the product is a gift card
diff --git a/data-transformations/naming-conventions/dimension-columns.mdx b/data-transformations/naming-conventions/dimension-columns.mdx
index a0fcceb..a231398 100644
--- a/data-transformations/naming-conventions/dimension-columns.mdx
+++ b/data-transformations/naming-conventions/dimension-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Dimension Columns'
-description: ''
-icon: ''
+description: 'How we name dimension columns (attributes) for consistent filtering and grouping.'
+icon: "tags"
---
-
### Overview
A dimension will always consist of an `entity` (e.g. order, customer) and a `dimension`, which is a
@@ -27,4 +26,4 @@ In some cases, dimension columns will have modifiers. As with metrics, modifiers
- `primary_order_payment_gateway`, where `order` is the `entity`, `payment_gateway` is the `dimension`, and `primary`
modifies this `entity_dimension` combination
- `most_recent_refund_date`, where `refund` is the `entity`, `date` is the `dimension`, and `most_recent`
-modifies this `entity_dimension` combination
\ No newline at end of file
+modifies this `entity_dimension` combination
diff --git a/data-transformations/naming-conventions/key-concepts.mdx b/data-transformations/naming-conventions/key-concepts.mdx
index f5802ec..60e4cfa 100644
--- a/data-transformations/naming-conventions/key-concepts.mdx
+++ b/data-transformations/naming-conventions/key-concepts.mdx
@@ -1,9 +1,8 @@
---
title: 'Key Concepts'
-description: ''
-icon: ''
+description: 'Definitions of the building blocks we use in naming conventions (entity, metric, dimension, modifier, prefix, suffix).'
+icon: "tags"
---
-
### Overview
Data warehouse naming conventions play an important role in ensuring that a user's data exploration and modeling experience is clear,
consistent, and efficient.
@@ -26,4 +25,4 @@ used to refine or alter the meaning of a metric or dimension by specifying a par
- `prefix`: A `prefix` is a string of characters added to the beginning of a column name to provide additional context, indicate a
specific source, or denote a particular type of data.
- `suffix`: A `suffix` is a string of characters added to the end of a column name to provide additional information about the type of data
-the column contains or the format of the data.
\ No newline at end of file
+the column contains or the format of the data.
diff --git a/data-transformations/naming-conventions/metric-columns.mdx b/data-transformations/naming-conventions/metric-columns.mdx
index a8a26e7..0741db7 100644
--- a/data-transformations/naming-conventions/metric-columns.mdx
+++ b/data-transformations/naming-conventions/metric-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Metric Columns'
-description: ''
-icon: ''
+description: 'How we name metric columns so they’re readable and consistent across the warehouse.'
+icon: "tags"
---
-
### Overview
A metric will always consist of an `entity` (e.g. order, customer), `dimension`, and in some cases, a `modifier`.
@@ -23,4 +22,4 @@ From there, any relevant entity modifiers will appear before the metric, as this
### Examples of metrics with modifiers
- `new_customer_order_net_revenue` where `order` is the `entity`, `net_order_revenue` is the `metric`, and `new_customer` modifies this `entity_metric` combination
-- `repeat_customer_order_count` where `order` is the `entity`, `count` is the `metric`, and `repeat_customer` modifies this `entity_metric` combination
\ No newline at end of file
+- `repeat_customer_order_count` where `order` is the `entity`, `count` is the `metric`, and `repeat_customer` modifies this `entity_metric` combination
diff --git a/data-transformations/naming-conventions/numerical-columns.mdx b/data-transformations/naming-conventions/numerical-columns.mdx
index 3e0ce94..cf31f0f 100644
--- a/data-transformations/naming-conventions/numerical-columns.mdx
+++ b/data-transformations/naming-conventions/numerical-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Numerical Columns'
-description: ''
-icon: ''
+description: 'Naming patterns for numeric metrics where aggregation/meaning is implied by convention.'
+icon: "tags"
---
-
### Overview
Numerical metric columns that do not explicitly reference a count or quantity have an implied `metric` definition in
@@ -23,4 +22,4 @@ Other examples of numerical values that don’t explicitly state the applied agg
- `message_unique_opens`
- `list_unsubscribes`
- `order_refunds`
-- `order_discounts`
\ No newline at end of file
+- `order_discounts`
diff --git a/data-transformations/naming-conventions/sourcemedium-proprietary-columns.mdx b/data-transformations/naming-conventions/sourcemedium-proprietary-columns.mdx
index 91e5106..f3be298 100644
--- a/data-transformations/naming-conventions/sourcemedium-proprietary-columns.mdx
+++ b/data-transformations/naming-conventions/sourcemedium-proprietary-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Proprietary Columns'
-description: ''
-icon: ''
+description: 'How to recognize SourceMedium-derived columns (the `sm_` prefix) and what they represent.'
+icon: "tags"
---
-
### Overview
The prefix `sm_` in a column name indicates that the column is proprietary to SourceMedium, meaning that the data contained within is a
@@ -11,4 +10,4 @@ function of SourceMedium's data transformations. This prefix helps to quickly id
materially enriched through a process of cleaning or imputing.
For example, `sm_source_medium` is a field derived from last-click attribution data from Shopify, Google Analytics, GA4, Elevar,
-Blotout, Littledata, referring domains, and other sources of last-click UTM parameters.
\ No newline at end of file
+Blotout, Littledata, referring domains, and other sources of last-click UTM parameters.
diff --git a/data-transformations/naming-conventions/table-names.mdx b/data-transformations/naming-conventions/table-names.mdx
index f788c27..ab973cc 100644
--- a/data-transformations/naming-conventions/table-names.mdx
+++ b/data-transformations/naming-conventions/table-names.mdx
@@ -1,9 +1,8 @@
---
title: 'Table Names'
-description: ''
-icon: ''
+description: 'How we name tables (`fct_`, `dim_`, `obt_`, `rpt_`) so datasets are easy to navigate.'
+icon: "tags"
---
-
### Table Structure Overview
- `fct`: Each record in a fact (`fct`) table represents a unique event or transaction, characterized by metrics or measurements
such as sales amount or units sold
@@ -20,4 +19,4 @@ tables we generate through our data modeling.__
- `fct` table name formula: `fct_{{ entity }}_{{ verb }}`
- `dim` table name formula: `dim_{{ dimension }}`
- `obt` table name formula: `obt_{{ entity }}`
-- `rpt` table name formula: `rpt_{{ entity }}_summary_{{ aggregation_granularity }}`
\ No newline at end of file
+- `rpt` table name formula: `rpt_{{ entity }}_summary_{{ aggregation_granularity }}`
diff --git a/data-transformations/naming-conventions/time-columns.mdx b/data-transformations/naming-conventions/time-columns.mdx
index fce83d1..71e386e 100644
--- a/data-transformations/naming-conventions/time-columns.mdx
+++ b/data-transformations/naming-conventions/time-columns.mdx
@@ -1,9 +1,8 @@
---
title: 'Time Columns'
-description: ''
-icon: ''
+description: 'How we name timestamps and datetimes (including localized time) across SourceMedium tables.'
+icon: "tags"
---
-
### Overview
Time columns are designated to represent either a timestamp or a datetime value associated with an
@@ -20,4 +19,4 @@ to denote the local time context.
* `order_processed_at`, where `order` is the `entity`, `processed` is the `attribute`, and `_at` indicates a timestamp
* `customer_created_at_local_datetime`, where `customer` is the `entity`, `created_at` is the `dimension`,
- and `_local_datetime` indicates a localized datetime
\ No newline at end of file
+ and `_local_datetime` indicates a localized datetime
diff --git a/data-transformations/order-segmentation/index.mdx b/data-transformations/order-segmentation/index.mdx
new file mode 100644
index 0000000..da5e029
--- /dev/null
+++ b/data-transformations/order-segmentation/index.mdx
@@ -0,0 +1,52 @@
+---
+title: "Order Segmentation"
+description: "How SourceMedium classifies orders by sales channel and order type for reporting and analysis"
+icon: "layer-group"
+---
+
+Order segmentation classifies each order into meaningful groups for reporting and analysis. These classifications power filters, breakdowns, and metrics throughout your dashboards.
+
+## Key Segmentation Dimensions
+
+
+
+ Groups orders by sales channel, integration path, acquisition source, and special order types
+
+
+ Subscription vs one-time classification using multi-signal detection
+
+
+
+## How Segmentation Works
+
+Each segmentation dimension uses a **determination hierarchy** that evaluates multiple signals to assign the correct classification. The system prioritizes explicit signals (like platform integrations and exclusion tags) over inferred signals (like order tags and UTMs).
+
+For example, a TikTok Shop order from a direct integration is always classified as `TikTok Shop`—even if your config sheet has a rule that would otherwise match it.
+
+
+See each dimension's page for the specific hierarchy and signal priority used.
+
+
+## Customizing Segmentation
+
+You can override default channel assignments using the **Channel Mapping** tab in your configuration sheet. This allows you to:
+
+- Map specific UTM patterns to custom channels
+- Group orders by discount codes
+- Segment by order tags or SKUs
+- Assign orders to vendors for cost tracking
+
+
+ Step-by-step guide to setting up custom channel mapping rules
+
+
+## Related Resources
+
+
+
+ Full list of available dimensions including sm_channel and sm_sub_channel
+
+
+ How UTM attribution data is selected when multiple sources exist
+
+
diff --git a/data-transformations/order-segmentation/order-type.mdx b/data-transformations/order-segmentation/order-type.mdx
new file mode 100644
index 0000000..8a9795c
--- /dev/null
+++ b/data-transformations/order-segmentation/order-type.mdx
@@ -0,0 +1,159 @@
+---
+title: "Order Type (sm_order_type)"
+description: "How SourceMedium classifies orders as subscription vs one-time purchases"
+sidebarTitle: "Order Type"
+icon: "repeat"
+---
+
+The `sm_order_type` field classifies whether an order is a subscription or one-time purchase. This classification is essential for subscription analytics, cohort analysis, and LTV calculations.
+
+## Order Type Values
+
+| Value | Description |
+|-------|-------------|
+| `subscription` | Recurring subscription order |
+| `one_time` | Non-subscription purchase |
+| `subscription_&_one_time` | Mixed order containing both subscription and one-time items |
+
+## How Order Type is Determined
+
+Order type classification uses a multi-signal approach evaluated at the **line item level**, then rolled up to the order. The system checks multiple signals in priority order:
+
+### Signal Priority (Highest to Lowest)
+
+| Priority | Signal | Result |
+|----------|--------|--------|
+| 1 | Amazon Subscribe & Save line item match | `Subscription` |
+| 2 | `prepaid` + subscription tag in order tags | `Subscription - Prepaid` |
+| 3 | Subscription platform line item type (ReCharge, Retextion) | Per platform classification |
+| 4 | Shopify Subscription Contract app ID | `Subscription` |
+| 5 | Order tags matching subscription patterns | `Subscription` |
+| 6 | Line item `is_from_subscription` flag | `Subscription` |
+| 7 | **Default** | `One-time` |
+
+### Subscription Tag Patterns
+
+The system recognizes these tag patterns (case-insensitive):
+
+- `Subscription`, `SubscriptionActive`
+- `recurring_order`, `recurring-order`
+- `subscription_order_loop`
+- `first_subscription_order`, `first-subscription`
+- `Luna Subscription`, `Ordergroove Trigger Order`
+
+
+The final `sm_order_type` on `dim_orders` uses `COALESCE(line_level_type, 'One-time')`, so orders always have a value—never null.
+
+
+### Subscription Platform Integration
+
+When you have a direct integration with a subscription platform, line-level data provides more accurate classification:
+
+| Platform | Data Source |
+|----------|-------------|
+| ReCharge | Line item type from ReCharge API |
+| Retextion | Line item type from Retextion API |
+| Chargebee | Invoice line subscription sequence |
+| Amazon Subscribe & Save | SKU-level subscription matching |
+
+## Related Dimensions
+
+### is_subscription_order
+
+A boolean convenience field derived from `sm_order_type`:
+
+```sql
+SELECT
+ sm_order_type,
+ sm_order_type = 'subscription' AS is_subscription_order
+FROM `your_project.sm_transformed_v2.dim_orders`
+WHERE sm_order_type IS NOT NULL
+LIMIT 10;
+```
+
+### order_sequence
+
+Customer lifecycle classification based on order position:
+
+| Value | Description |
+|-------|-------------|
+| `1st_order` | Customer's first order (new customer) |
+| `repeat_order` | Any subsequent order (returning customer) |
+
+### subscription_order_sequence
+
+Subscription-specific lifecycle classification:
+
+| Value | Description |
+|-------|-------------|
+| `1st_sub_order` | Customer's first subscription purchase |
+| `recurring_sub_order` | Subscription renewal or subsequent subscription order |
+| `one_time_order` | Non-subscription order |
+
+## Using Order Type in Analysis
+
+### Filter to Subscription Orders
+
+```sql
+SELECT COUNT(*) AS subscription_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND sm_order_type = 'subscription';
+-- or equivalently
+SELECT COUNT(*) AS subscription_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND is_subscription_order = TRUE;
+```
+
+### Separate Subscription vs One-time Metrics
+
+```sql
+SELECT
+ sm_order_type,
+ COUNT(*) as order_count,
+ SUM(order_net_revenue) as revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+GROUP BY sm_order_type
+```
+
+### Subscription Cohort Analysis
+
+Use `subscription_order_sequence` to analyze subscription retention:
+
+```sql
+SELECT
+ DATE_TRUNC(order_processed_at, MONTH) as cohort_month,
+ subscription_order_sequence,
+ COUNT(DISTINCT sm_customer_key) as customers
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND is_subscription_order = TRUE
+GROUP BY 1, 2
+```
+
+## Best Practices
+
+### Ensure Consistent Tagging
+
+For accurate subscription classification in Shopify, ensure your subscription app consistently applies subscription tags to orders. Most subscription apps (ReCharge, Skio, etc.) do this automatically.
+
+### Validate with Subscription Platform Data
+
+If you have a direct subscription platform integration, compare the `sm_order_type` classification against your subscription platform's data to ensure accuracy.
+
+### Use for LTV Segmentation
+
+Subscription and one-time customers often have very different lifetime value patterns. Use `sm_order_type` to segment your LTV analysis accordingly.
+
+## Related Resources
+
+
+
+ Analyze subscription and one-time customer retention
+
+
+ Filter and analyze orders by type
+
+
diff --git a/data-transformations/order-segmentation/sales-channel.mdx b/data-transformations/order-segmentation/sales-channel.mdx
new file mode 100644
index 0000000..6696caf
--- /dev/null
+++ b/data-transformations/order-segmentation/sales-channel.mdx
@@ -0,0 +1,173 @@
+---
+title: "Sales Channel (sm_channel)"
+description: "How SourceMedium determines the channel for each order"
+sidebarTitle: "Sales Channel"
+icon: "store"
+---
+
+The `sm_channel` field groups orders for reporting based on:
+
+- **Sales channel** — Online DTC, Amazon, Retail, TikTok Shop
+- **Integration path** — direct integration (`Amazon`) vs flowing through Shopify (`Amazon via Shopify`)
+- **Acquisition source** — Partners / Affiliates (e.g., GRIN)
+- **Special order types** — Exchanges, Draft Orders, Excluded
+
+This is one of the most important dimensions for segmenting your business performance.
+
+## Standard Channel Values
+
+| Channel | Description |
+|---------|-------------|
+| `online_dtc` | Direct-to-consumer orders from your online store |
+| `amazon` | Orders from Amazon Seller Central (direct integration) |
+| `amazon_via_shopify` | Amazon orders flowing through Shopify |
+| `amazon_multi_channel_fulfillment` | Amazon MCF fulfillment orders (when present) |
+| `retail` | Point-of-sale and physical retail orders |
+| `wholesale` | B2B and bulk orders |
+| `partners_/_affiliates` | GRIN and affiliate platform orders |
+| `exchanged` | Exchange and replacement orders |
+| `draft_orders` | Manually created draft orders |
+| `excluded` | Orders tagged with `sm-exclude-order` |
+
+## Channel Determination Hierarchy
+
+SourceMedium evaluates each order through this priority sequence:
+
+### Priority 1: Exclusion Tag
+
+Orders with the `sm-exclude-order` tag are always assigned to the **Excluded** channel, regardless of any other signals.
+
+```sql
+-- This tag takes absolute precedence
+SELECT
+ sm_order_key,
+ sm_channel,
+ order_tags_csv
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND REGEXP_CONTAINS(LOWER(order_tags_csv), r'(^|,\\s*)sm-exclude-order(\\s*,|$)')
+LIMIT 50;
+```
+
+
+Excluded orders won't appear in Executive Summary metrics or LTV calculations. Use this tag for test orders, internal orders, or any orders that shouldn't count in analytics.
+
+
+### Priority 2: Source System Override
+
+Orders from direct platform integrations (not flowing through Shopify) are assigned based on their source:
+
+| Source System | Assigned Channel |
+|---------------|------------------|
+| `tiktok_shop` | TikTok Shop |
+| `amazon` | Amazon |
+
+### Priority 3: Shopify Marketplace Detection
+
+For Shopify orders, marketplace signals derived from the order source trigger specific channel mappings:
+
+| Condition | Assigned Channel |
+|-----------|------------------|
+| Order source contains `amazon` | Amazon via Shopify |
+| Sales channel is `TikTok Shop` | TikTok Shop via Shopify |
+
+### Priority 4: Config Sheet Rules
+
+Your custom channel mapping rules are evaluated next. These rules can match on:
+
+| Attribute | Description | Example |
+|-----------|-------------|---------|
+| `source` | UTM source | `utm_source=influencer` |
+| `medium` | UTM medium | `utm_medium=affiliate` |
+| `source_medium` | Combined source/medium | `facebook / cpc` |
+| `campaign` | UTM campaign | `utm_campaign=wholesale_q1` |
+| `discount_codes` | Applied discount codes | `WHOLESALE50` |
+| `order_tags` | Shopify order tags | `wholesale`, `b2b` |
+| `skus` | Product SKUs in the order | `BULK-*` |
+| `shopify_sales_channel` | Shopify app/source | `Shop App` |
+
+
+ Step-by-step guide to setting up your own channel mapping rules
+
+
+### Priority 5: Default Logic
+
+If no config sheet rules match, these defaults apply based on order attributes:
+
+| Condition | Assigned Channel |
+|-----------|------------------|
+| GRIN app orders | Partners / Affiliates |
+| Tags contain `wholesale`, `faire`, `wholesaler` | Wholesale |
+| Tags contain `exchange`, `returnly_exchange`, `ex-###` | Exchanged |
+| POS or Leap app orders | Retail |
+| Draft order source | Draft Orders |
+| Tags contain `mirakl` | Mirakl |
+| **Everything else** | Online DTC |
+
+## Sub-Channel (sm_sub_channel)
+
+The `sm_sub_channel` field provides additional granularity within a channel. The value is determined by:
+
+1. **For Amazon orders**: Derived from fulfillment channel:
+ - `Fulfilled by Amazon` — FBA orders
+ - `Fulfilled by Merchant` — Merchant-fulfilled orders
+
+2. **For all other orders**: Uses your config sheet `sub_channel` if set, otherwise falls back to the channel name, or `Unknown` as a last resort
+
+
+Sub-channels are most commonly used to segment Online DTC orders by marketing source (e.g., separating influencer orders from general paid social).
+
+
+## Debugging Channel Assignment
+
+To understand why an order landed in a specific channel, start by pulling the mapping outputs and the most common inputs that influence mapping (sales channel + UTMs).
+
+```sql
+SELECT
+ sm_order_key,
+ sm_channel,
+ sm_sub_channel,
+ sm_default_channel,
+ sm_order_sales_channel,
+ source_system_sales_channel,
+ sm_utm_source_medium,
+ sm_utm_campaign
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= DATETIME_SUB(CURRENT_DATETIME(), INTERVAL 30 DAY)
+ORDER BY order_processed_at_local_datetime DESC
+LIMIT 200;
+```
+
+If the inputs don’t line up with your expectations, that typically points to missing UTMs or an override rule that needs to be added/updated.
+
+## Best Practices
+
+### Use Tags for Non-UTM Segmentation
+
+For orders that don't have reliable UTM data (wholesale, B2B, exchanges), use Shopify order tags and set up config sheet rules to match them.
+
+### Set Up Shopify Flow Automation
+
+Automate consistent tagging with Shopify Flow:
+
+```liquid
+IF order.customer.tags CONTAINS "wholesale"
+OR order.discount_code CONTAINS "WHOLESALE-"
+THEN add_tag "wholesale"
+```
+
+### Review Channel Distribution Regularly
+
+Check the **Orders Deep Dive** module to ensure orders are being assigned to the expected channels. If you see unexpected `Online DTC` orders, they may need config sheet rules.
+
+## Related Resources
+
+
+
+ Detailed explanation of the channel mapping system
+
+
+ Analyze orders by channel in your dashboard
+
+
diff --git a/data-transformations/philosophy.mdx b/data-transformations/philosophy.mdx
index 11295b8..729e5a9 100644
--- a/data-transformations/philosophy.mdx
+++ b/data-transformations/philosophy.mdx
@@ -1,7 +1,7 @@
---
title: 'Modeling Philosophy'
description: 'How we help amplify your data capabilities'
-icon: ''
+icon: "gear"
---
## Bootstrapping Data Teams
@@ -48,4 +48,4 @@ dashboards, or operational reports, and are optimized for performance and clarit
### Summary tables
Summary tables, which include `summary` in the table name, are a variant of `rpt` tables that focus on providing aggregated views of
data, summarizing detailed information into higher-level insights. `summary` tables might aggregate data by time periods, geographic regions,
-product categories, or other dimensions to offer concise, actionable information derived from more granular datasets.
\ No newline at end of file
+product categories, or other dimensions to offer concise, actionable information derived from more granular datasets.
diff --git a/desktop.ini b/desktop.ini
deleted file mode 100644
index ab17096..0000000
--- a/desktop.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[ViewState]
-Mode=
-Vid=
-FolderType=Documents
diff --git a/docs.json b/docs.json
index 71a446a..4dc1e99 100644
--- a/docs.json
+++ b/docs.json
@@ -11,84 +11,20 @@
"navigation": {
"tabs": [
{
- "tab": "What Is SourceMedium",
- "groups": [
- {
- "group": "About",
- "pages": [
- "help-center/what-is-sourcemedium"
- ]
- },
- {
- "group": "FAQs",
- "pages": [
- "help-center/faq/cold-start-guide-home",
- {
- "group": "Data Clarification & Discrepancies",
- "pages": [
- "help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard",
- "help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match",
- "help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue",
- "help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers",
- "help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview",
- "help-center/faq/data-faqs/what-attribution-windows-does-sourcemedoum-report-on-for-marketing-platforms",
- "help-center/faq/data-faqs/how-does-stripe-metadata-work",
- "help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting",
- "help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report",
- "help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature",
- "help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration",
- "help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard"
- ]
- },
- {
- "group": "Dashboard Functionality",
- "pages": [
- "help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview",
- "help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium",
- "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data",
- "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv",
- "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance"
- ]
- },
- {
- "group": "Configuration Sheet",
- "pages": [
- "help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency",
- "help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges"
- ]
- },
- {
- "group": "Account Management",
- "pages": [
- "help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work",
- "help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group",
- "help-center/faq/account-management-faqs/how-do-i-invite-users-to-my-dashboard",
- "help-center/faq/account-management-faqs/bigquerey-csv-upload-guide",
- "help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel",
- "help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report",
- "help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey",
- "help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium",
- "help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data",
- "help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution",
- "help-center/faq/account-management-faqs/what-to-know-about connecting-google-analytics-to-sourcemedium",
- "help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire",
- "help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce"
- ]
- }
- ]
- }
- ]
- },
- {
- "tab": "Onboarding",
+ "tab": "Overview",
"groups": [
{
"group": "Getting Started",
"pages": [
+ "index",
"onboarding/getting-started/getting-started-checklist",
+ "onboarding/getting-started/data-volume-assessment",
+ "onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b",
"onboarding/getting-started/level-1-data-checklist",
"onboarding/getting-started/level-2-data-checklist",
+ "onboarding/getting-started/level-3-data-checklist",
"onboarding/getting-started/how-to-work-with-the-sourcemedium-team",
+ "help-center/core-concepts/data-transformation/data-architecture",
{
"group": "The Analytical Mindset",
"pages": [
@@ -98,21 +34,47 @@
}
]
},
+ {
+ "group": "Product Overview",
+ "pages": [
+ "help-center/what-is-sourcemedium",
+ "onboarding/getting-started/intro-to-sm",
+ "onboarding/getting-started/why-source-medium"
+ ]
+ },
+ {
+ "group": "Access & Permissions",
+ "pages": [
+ "onboarding/getting-started/how-to-manage-user-access",
+ "onboarding/analytics-tools/google-groups-access-control",
+ "help-center/slack-bot-setup"
+ ]
+ },
{
"group": "Analytics Tools",
"pages": [
- "onboarding/analytics-tools/learn-looker-studio",
- "onboarding/analytics-tools/learn-bigquery"
+ "onboarding/analytics-tools/looker-studio-guide",
+ "onboarding/analytics-tools/bigquery-essentials",
+ "onboarding/analytics-tools/connect-bigquery-to-looker-studio",
+ "onboarding/analytics-tools/connect-to-other-bi-tools"
+ ]
+ },
+ {
+ "group": "Resources",
+ "pages": [
+ "help-center/glossary",
+ "help-center/template-gallery"
]
}
]
},
{
- "tab": "Data Integrations & Inputs",
+ "tab": "Connect Your Data",
"groups": [
{
"group": "Integrations",
"pages": [
+ "data-inputs/data-inputs-overview",
"data-inputs/platform-integration-instructions/all-available-integrations",
{
"group": "Ecommerce & Subscription",
@@ -120,7 +82,8 @@
{
"group": "Shopify",
"pages": [
- "data-inputs/platform-integration-instructions/shopify-integration"
+ "data-inputs/platform-integration-instructions/shopify-integration",
+ "data-inputs/platform-supporting-resources/shopify/backfilling-utm-attribution-via-checkout-attributes"
]
},
{
@@ -354,12 +317,6 @@
"data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations"
]
},
- {
- "group": "(Premium) Mailchimp",
- "pages": [
- "data-inputs/platform-integration-instructions/mailchimp-integration"
- ]
- },
{
"group": "(Premium) HubSpot",
"pages": [
@@ -377,18 +334,6 @@
{
"group": "Proprietary Partner Integrations",
"pages": [
- {
- "group": "(Beta) Elevar",
- "pages": [
- "data-inputs/platform-integration-instructions/elevar-integration"
- ]
- },
- {
- "group": "(Beta) Littledata",
- "pages": [
- "data-inputs/platform-integration-instructions/littledata-integration"
- ]
- },
{
"group": "Global-E",
"pages": [
@@ -396,9 +341,9 @@
]
},
{
- "group": "Fairing",
+ "group": "FERMÀT",
"pages": [
- "data-inputs/platform-integration-instructions/fairing-integration"
+ "data-inputs/platform-integration-instructions/fermat-integration"
]
},
{
@@ -418,19 +363,13 @@
"pages": [
"data-inputs/platform-integration-instructions/tapcart-integration"
]
- },
- {
- "group": "Tatari",
- "pages": [
- "data-inputs/platform-integration-instructions/tatari-integration"
- ]
}
]
}
]
},
{
- "group": "Proprietary Data Enrichment Tools",
+ "group": "Configuration Sheet",
"pages": [
"data-inputs/configuration-sheet/config-sheet-overview",
{
@@ -477,81 +416,74 @@
]
},
{
- "tab": "Data Transformation",
+ "tab": "Understand Your Data",
"groups": [
{
- "group": "Transformation",
+ "group": "Core Concepts",
"pages": [
"data-transformations/philosophy",
+ "help-center/core-concepts/data-health",
+ "help-center/core-concepts/data-transformation/transformation-vs-cleaning",
+ "help-center/core-concepts/data-transformation/data-freshness",
"data-transformations/data-cleaning",
- "data-transformations/data-enrichment"
+ "data-transformations/data-enrichment",
+ {
+ "group": "Data Definitions",
+ "pages": [
+ "help-center/core-concepts/data-definitions/index",
+ "help-center/core-concepts/data-definitions/is-order-sm-valid",
+ "help-center/core-concepts/data-definitions/revenue-fields",
+ "help-center/core-concepts/data-definitions/refund-logic",
+ "help-center/core-concepts/data-definitions/subscription-flags",
+ "help-center/core-concepts/data-definitions/channel-mapping",
+ "help-center/core-concepts/data-definitions/utm-normalization",
+ "help-center/core-concepts/data-definitions/event-and-journey-deduping"
+ ]
+ }
]
},
{
- "group": "Naming Conventions",
+ "group": "Attribution",
"pages": [
- "data-transformations/naming-conventions/key-concepts",
- "data-transformations/naming-conventions/table-names",
- "data-transformations/naming-conventions/metric-columns",
- "data-transformations/naming-conventions/dimension-columns",
- "data-transformations/naming-conventions/numerical-columns",
- "data-transformations/naming-conventions/sourcemedium-proprietary-columns",
- "data-transformations/naming-conventions/boolean-columns",
- "data-transformations/naming-conventions/time-columns"
+ "help-center/core-concepts/attribution/attribution-in-sourcemedium",
+ "help-center/core-concepts/attribution/utm-setup",
+ "help-center/core-concepts/attribution/direct-none",
+ "help-center/core-concepts/attribution/first-party-attribution",
+ "help-center/core-concepts/attribution/zero-party-attribution",
+ "data-transformations/attribution-source-hierarchy",
+ "data-inputs/attribution-health/index",
+ "help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey"
+ ]
+ },
+ {
+ "group": "Order Segmentation",
+ "pages": [
+ "data-transformations/order-segmentation/index",
+ "data-transformations/order-segmentation/sales-channel",
+ "data-transformations/order-segmentation/order-type"
+ ]
+ },
+ {
+ "group": "Customer Record",
+ "pages": [
+ "help-center/core-concepts/customer-record-enrichment/index",
+ "help-center/core-concepts/demographics/demographic-data-sources"
]
}
]
},
{
- "tab": "Data Activation",
+ "tab": "Use Your Data",
"groups": [
{
- "group": "Managed Data Warehouse",
- "pages": [
- "data-activation/managed-data-warehouse/overview",
- "data-activation/managed-data-warehouse/bi-tools",
- {
- "group": "SourceMedium Templates",
- "pages": [
- {
- "group": "Looker Studio",
- "pages": [
- "data-activation/template-resources/looker-studio-template-copy-instructions",
- "data-activation/template-resources/sm-looker-report-template-directory"
- ]
- }
- ]
- },
- {
- "group": "SourceMedium Tables",
- "pages": [
- "data-activation/data-tables/sm_transformed_v2/dim_customer_addresses",
- "data-activation/data-tables/sm_transformed_v2/dim_customers",
- "data-activation/data-tables/sm_transformed_v2/dim_order_discounts",
- "data-activation/data-tables/sm_transformed_v2/dim_order_lines",
- "data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines",
- "data-activation/data-tables/sm_transformed_v2/dim_order_taxes",
- "data-activation/data-tables/sm_transformed_v2/dim_orders",
- "data-activation/data-tables/sm_transformed_v2/dim_product_variants",
- "data-activation/data-tables/sm_transformed_v2/dim_times",
- "data-activation/data-tables/sm_transformed_v2/fct_orders_placed",
- "data-activation/data-tables/sm_transformed_v2/fct_refunds_processed",
- "data-activation/data-tables/sm_transformed_v2/obt_customers",
- "data-activation/data-tables/sm_transformed_v2/obt_order_lines",
- "data-activation/data-tables/sm_transformed_v2/obt_orders",
- "data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily",
- "data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily"
- ]
- }
- ]
- },
- {
- "group": "Managed BI",
+ "group": "Managed BI (Dashboards)",
"pages": [
+ "data-activation/managed-bi-v1/overview",
"data-activation/managed-bi-v1/core-dashboard-features",
{
- "group": "Modules",
+ "group": "Dashboard Modules",
"pages": [
+ "data-activation/managed-bi-v1/modules/index",
"data-activation/managed-bi-v1/modules/executive-summary-module",
"data-activation/managed-bi-v1/modules/yoy-performance-module",
"data-activation/managed-bi-v1/modules/marketing-overview-module",
@@ -562,6 +494,7 @@
"data-activation/managed-bi-v1/modules/traffic-deep-dive-module",
"data-activation/managed-bi-v1/modules/emails-general-module",
"data-activation/managed-bi-v1/modules/emails-conversions-module",
+ "data-activation/managed-bi-v1/modules/post-purchase-survey-module",
"data-activation/managed-bi-v1/modules/ltv-retention-module",
"data-activation/managed-bi-v1/modules/repurchase-analysis-module",
"data-activation/managed-bi-v1/modules/new-customer-analysis-module",
@@ -574,6 +507,212 @@
]
}
]
+ },
+ {
+ "group": "Managed Data Warehouse",
+ "pages": [
+ "data-activation/managed-data-warehouse/overview",
+ "data-activation/managed-data-warehouse/modeling",
+ "data-activation/managed-data-warehouse/bi-tools",
+ "data-activation/managed-data-warehouse/metrics-and-semantic-layer"
+ ]
+ },
+ {
+ "group": "Templates",
+ "pages": [
+ {
+ "group": "Looker Studio",
+ "pages": [
+ "data-activation/template-resources/looker-studio-template-copy-instructions",
+ "data-activation/template-resources/sm-looker-report-template-directory",
+ "data-activation/template-resources/sm-looker-data-source-template-directory",
+ "data-activation/template-resources/copying-sm-report-templates",
+ "data-activation/template-resources/copying-sm-data-source-templates"
+ ]
+ },
+ {
+ "group": "SQL Query Library",
+ "pages": [
+ "data-activation/template-resources/sql-query-library"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Common Analyses",
+ "pages": [
+ "help-center/common-analyses/common-analysis-template",
+ "help-center/common-analyses/top-selling-products",
+ "help-center/common-analyses/top-converting-products",
+ "help-center/common-analyses/roas",
+ "help-center/common-analyses/customer-retention",
+ "help-center/common-analyses/subscription-program-retention",
+ "help-center/common-analyses/revenue-retention",
+ "help-center/common-analyses/cohort-lto",
+ "help-center/common-analyses/cohort-ltv",
+ "help-center/common-analyses/understanding-your-gross-profit",
+ "help-center/common-analyses/understanding-your-contribution-margin"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "Data Dictionary",
+ "groups": [
+ {
+ "group": "Data Dictionary",
+ "pages": [
+ "onboarding/data-docs/metrics",
+ "onboarding/data-docs/dimensions"
+ ]
+ },
+ {
+ "group": "Table Schemas",
+ "pages": [
+ "data-activation/data-tables/sm_transformed_v2/index",
+ "data-activation/data-tables/sm_transformed_v2/dim_customer_addresses",
+ "data-activation/data-tables/sm_transformed_v2/dim_customers",
+ "data-activation/data-tables/sm_transformed_v2/dim_order_discounts",
+ "data-activation/data-tables/sm_transformed_v2/dim_order_lines",
+ "data-activation/data-tables/sm_transformed_v2/dim_order_shipping_lines",
+ "data-activation/data-tables/sm_transformed_v2/dim_order_taxes",
+ "data-activation/data-tables/sm_transformed_v2/dim_orders",
+ "data-activation/data-tables/sm_transformed_v2/dim_product_variants",
+ "data-activation/data-tables/sm_transformed_v2/fct_orders_placed",
+ "data-activation/data-tables/sm_transformed_v2/fct_refunds_processed",
+ "data-activation/data-tables/sm_transformed_v2/obt_customer_support_tickets",
+ "data-activation/data-tables/sm_transformed_v2/obt_customers",
+ "data-activation/data-tables/sm_transformed_v2/obt_funnel_event_history",
+ "data-activation/data-tables/sm_transformed_v2/obt_order_lines",
+ "data-activation/data-tables/sm_transformed_v2/obt_orders",
+ "data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily",
+ "data-activation/data-tables/sm_transformed_v2/rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily",
+ "data-activation/data-tables/sm_transformed_v2/rpt_funnel_events_performance_hourly",
+ "data-activation/data-tables/sm_transformed_v2/rpt_outbound_message_performance_daily"
+ ]
+ },
+ {
+ "group": "Metadata Tables",
+ "pages": [
+ "data-activation/data-tables/sm_metadata/dim_data_dictionary",
+ "data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog"
+ ]
+ },
+ {
+ "group": "Experimental Tables",
+ "pages": [
+ "data-activation/data-tables/sm_experimental/index",
+ "data-activation/data-tables/sm_experimental/rpt_ad_attribution_performance_daily",
+ "data-activation/data-tables/sm_experimental/obt_purchase_journeys_with_mta_models"
+ ]
+ },
+ {
+ "group": "Naming Conventions",
+ "pages": [
+ "data-transformations/naming-conventions/key-concepts",
+ "data-transformations/naming-conventions/table-names",
+ "data-transformations/naming-conventions/metric-columns",
+ "data-transformations/naming-conventions/dimension-columns",
+ "data-transformations/naming-conventions/numerical-columns",
+ "data-transformations/naming-conventions/sourcemedium-proprietary-columns",
+ "data-transformations/naming-conventions/boolean-columns",
+ "data-transformations/naming-conventions/time-columns"
+ ]
+ },
+ {
+ "group": "Raw Data Source Overviews",
+ "pages": [
+ {
+ "group": "Ecommerce & Subscription",
+ "pages": [
+ "help-center/raw-data-source-overviews/amazon-sc-overview",
+ "help-center/raw-data-source-overviews/chargebee-overview",
+ "help-center/raw-data-source-overviews/stripe-overview"
+ ]
+ },
+ {
+ "group": "Marketing & Advertising",
+ "pages": [
+ "help-center/raw-data-source-overviews/meta-ads-overview",
+ "help-center/raw-data-source-overviews/google-ads-overview"
+ ]
+ },
+ {
+ "group": "Email & CRM",
+ "pages": [
+ "help-center/raw-data-source-overviews/klaviyo-overview",
+ "help-center/raw-data-source-overviews/hubspot-overview"
+ ]
+ },
+ {
+ "group": "Configuration Sheet",
+ "pages": [
+ "help-center/raw-data-source-overviews/configuration-sheet/configuration-sheet-overview",
+ "help-center/raw-data-source-overviews/configuration-sheet/schema",
+ "help-center/raw-data-source-overviews/configuration-sheet/sales-tab",
+ "help-center/raw-data-source-overviews/configuration-sheet/channel-mapping-tab",
+ "help-center/raw-data-source-overviews/configuration-sheet/targets-tab",
+ {
+ "group": "Costs",
+ "pages": [
+ "help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs",
+ "help-center/raw-data-source-overviews/configuration-sheet/costs/shipping-costs",
+ "help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs",
+ "help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees",
+ "help-center/raw-data-source-overviews/configuration-sheet/costs/marketing-costs"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "AI Analyst",
+ "groups": [
+ {
+ "group": "Getting Started",
+ "pages": [
+ "ai-analyst/index",
+ "ai-analyst/what-you-can-ask",
+ "ai-analyst/setup",
+ "ai-analyst/understanding-results",
+ "ai-analyst/building-trust"
+ ]
+ },
+ {
+ "group": "Workflows",
+ "pages": [
+ "ai-analyst/workflows/index",
+ "ai-analyst/workflows/standard",
+ "ai-analyst/workflows/deep-analysis",
+ "ai-analyst/workflows/knowledge"
+ ]
+ },
+ {
+ "group": "Diagnostics",
+ "pages": [
+ "ai-analyst/diagnostics/index",
+ "ai-analyst/diagnostics/data-health",
+ "ai-analyst/diagnostics/attribution-health"
+ ]
+ },
+ {
+ "group": "Agent Skills",
+ "pages": [
+ "ai-analyst/agent-skills/index",
+ "ai-analyst/agent-skills/sm-bigquery-analyst",
+ "ai-analyst/agent-skills/bigquery-access-request-template"
+ ]
+ },
+ {
+ "group": "Reference",
+ "pages": [
+ "ai-analyst/troubleshooting",
+ "ai-analyst/roadmap"
+ ]
}
]
},
@@ -581,41 +720,132 @@
"tab": "MTA",
"groups": [
{
- "group": "MTA",
+ "group": "Multi-Touch Attribution",
"pages": [
"mta/mta-overview",
+ "mta/mta-models",
+ {
+ "group": "MTA Features",
+ "pages": [
+ "mta/mta-email-sms-attribution",
+ "mta/mta-brand-campaign-attribution",
+ "mta/mta-channel-level-attribution"
+ ]
+ },
"mta/mta-dash-provisioning",
"mta/mta-faqs",
"mta/mta-advanced-documentation"
]
}
]
+ },
+ {
+ "tab": "FAQs",
+ "groups": [
+ {
+ "group": "Getting Help",
+ "pages": [
+ "faq",
+ "help-center/faq/cold-start-guide-home",
+ "onboarding/data-docs/data-hygeine/importance-of-good-data-hygeine"
+ ]
+ },
+ {
+ "group": "FAQs",
+ "pages": [
+ {
+ "group": "Dashboard Functionality",
+ "pages": [
+ "help-center/faq/dashboard-functionality-faqs/dashboard-functionality-faqs-home",
+ "help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview",
+ "help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium",
+ "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data",
+ "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv",
+ "help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance",
+ "help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting",
+ "help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report",
+ "help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature",
+ "help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration"
+ ]
+ },
+ {
+ "group": "Configuration Sheet",
+ "pages": [
+ "help-center/faq/configuration-sheet-faqs/configuration-sheet-faqs-home",
+ "help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency",
+ "help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges"
+ ]
+ },
+ {
+ "group": "Account Management",
+ "pages": [
+ "help-center/faq/account-management-faqs/account-management-faqs-home",
+ "help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work",
+ "help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate",
+ "help-center/faq/account-management-faqs/bigquery-csv-upload-guide",
+ "help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel",
+ "help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report",
+ "help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium",
+ "help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data",
+ "help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution",
+ "help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium",
+ "help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire",
+ "help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce",
+ "help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Troubleshooting",
+ "pages": [
+ "help-center/faq/data-faqs/data-faqs-home",
+ "help-center/faq/data-faqs/why-is-my-data-taking-so-long-to-load",
+ "help-center/faq/account-management-faqs/what-is-last-click-attribution",
+ "help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard",
+ "help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match",
+ "help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium",
+ "help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium",
+ "help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue",
+ "help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers",
+ "help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview",
+ "help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms",
+ "help-center/faq/data-faqs/how-does-stripe-metadata-work"
+ ]
+ }
+ ]
}
]
},
"logo": {
"light": "/logo/light.png",
- "dark": "/logo/dark.png"
+ "dark": "/logo/dark.png",
+ "href": "https://sourcemedium.com"
},
"appearance": {
"default": "light",
"strict": false
},
+ "seo": {
+ "metatags": {
+ "canonical": "https://sourcemedium.com/docs"
+ }
+ },
"navbar": {
"links": [
{
- "label": "Customer Case Studies",
- "href": "https://www.sourcemedium.com/case-study"
+ "label": "Customer stories",
+ "href": "https://sourcemedium.com/case-study/"
},
{
- "label": "Blog",
- "href": "https://www.sourcemedium.com/blog"
+ "label": "Integrations",
+ "href": "https://sourcemedium.com/integrations/"
}
],
"primary": {
"type": "button",
- "label": "Request a Demo",
- "href": "https://www.sourcemedium.com/book-demo-web"
+ "label": "Get started",
+ "href": "https://sourcemedium.com/request-demo"
}
},
"footer": {
@@ -627,9 +857,18 @@
"integrations": {
"ga4": {
"measurementId": "G-LKSGE9NY1B"
+ },
+ "posthog": {
+ "apiKey": "phc_yEZthPWGFIyJz42b7EPyqO7lPFRzjvDBJaw21cDcRmX",
+ "apiHost": "https://us.i.posthog.com",
+ "sessionRecording": true
}
},
"redirects": [
+ {
+ "source": "/data-activation/template-resources/sm-sql-recipe-directory",
+ "destination": "/data-activation/template-resources/sql-query-library"
+ },
{
"source": "/integrations",
"destination": "/data-inputs/platform-integration-instructions/all-available-integrations"
@@ -637,6 +876,110 @@
{
"source": "/data-inputs/platform-integration-instructions/twitter-integration",
"destination": "/data-inputs/platform-integration-instructions/x-integration"
+ },
+ {
+ "source": "/help-center/faq/account-management-faqs/what-to-know-about connecting-google-analytics-to-sourcemedium",
+ "destination": "/help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium"
+ },
+ {
+ "source": "/help-center/faq/account-management-faqs/what-to-know-about%20connecting-google-analytics-to-sourcemedium",
+ "destination": "/help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium"
+ },
+ {
+ "source": "/help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature",
+ "destination": "/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature"
+ },
+ {
+ "source": "/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedoum-report-on-for-marketing-platforms",
+ "destination": "/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms"
+ },
+ {
+ "source": "/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report",
+ "destination": "/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match"
+ },
+ {
+ "source": "/data-inputs/configuration-sheet",
+ "destination": "/data-inputs/configuration-sheet/config-sheet-overview"
+ },
+ {
+ "source": "/help-center/what-is-sourcemediumglossary",
+ "destination": "/help-center/glossary"
+ },
+ {
+ "source": "/help-center/what-is-sourcemediumarticles/template-gallery",
+ "destination": "/help-center/template-gallery"
+ },
+ {
+ "source": "/help-center/what-is-sourcemediumarticles/source-medium-report-analytics-slack-bot-setup",
+ "destination": "/help-center/slack-bot-setup"
+ },
+ {
+ "source": "/help-center/what-is-sourcemediumarticles/exclude-0-orders-feature-overview",
+ "destination": "/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/order_details_looker",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/obt_orders"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/executive_summary_looker",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily"
+ },
+ {
+ "source": "/data-transformations/attribution-waterfall",
+ "destination": "/data-transformations/attribution-source-hierarchy"
+ },
+ {
+ "source": "/data-inputs/platform-supporting-resources/ga4/improving-last-click-attribution",
+ "destination": "/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/customer_details_looker",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/obt_customers"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/order_details_dda",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/obt_orders"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/customer_details_dda",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/obt_customers"
+ },
+ {
+ "source": "/onboarding/data-docs/tables/executive_summary_dda",
+ "destination": "/data-activation/data-tables/sm_transformed_v2/rpt_executive_summary_daily"
+ },
+ {
+ "source": "/data-activation/managed-bi-v2/overview",
+ "destination": "/data-activation/managed-bi-v1/overview"
+ },
+ {
+ "source": "/data-activation/managed-bi-v2/modules/executive-summary",
+ "destination": "/data-activation/managed-bi-v1/modules/executive-summary-module"
+ },
+ {
+ "source": "/onboarding/analytics-tools/learn-bigquery",
+ "destination": "/onboarding/analytics-tools/bigquery-essentials"
+ },
+ {
+ "source": "/onboarding/analytics-tools/learn-looker-studio",
+ "destination": "/onboarding/analytics-tools/looker-studio-guide"
+ },
+ {
+ "source": "/onboarding/analytics-tools/creating-google-groups",
+ "destination": "/onboarding/analytics-tools/google-groups-access-control"
+ },
+ {
+ "source": "/onboarding/analytics-tools/sharing-access",
+ "destination": "/onboarding/analytics-tools/google-groups-access-control"
+ },
+ {
+ "source": "/help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group",
+ "destination": "/onboarding/analytics-tools/google-groups-access-control"
+ },
+ {
+ "source": "/help-center/faq/account-management-faqs/how-do-i-invite-users-to-my-dashboard",
+ "destination": "/onboarding/analytics-tools/looker-studio-guide"
}
]
-}
\ No newline at end of file
+}
diff --git a/faq.mdx b/faq.mdx
new file mode 100644
index 0000000..73a865c
--- /dev/null
+++ b/faq.mdx
@@ -0,0 +1,32 @@
+---
+title: "FAQs"
+description: "Quick answers and troubleshooting guides for SourceMedium dashboards, configuration, data discrepancies, and account setup."
+sidebarTitle: "FAQ Index"
+icon: "question-mark"
+---
+
+Browse the most common questions by category. If you’re troubleshooting a number mismatch, start with **Data FAQs**.
+
+## FAQ categories
+
+
+
+ Discrepancies, metric definitions, and reconciliation across systems.
+
+
+ Where to find things and how dashboard behaviors work.
+
+
+ Setup and ongoing maintenance for mapping and exclusions.
+
+
+ Access, security, uploads, and operational questions.
+
+
+ Multi-touch attribution setup and troubleshooting.
+
+
+ A guided set of links if you’re new to SourceMedium.
+
+
+
diff --git a/help-center/common-analyses/cohort-lto.mdx b/help-center/common-analyses/cohort-lto.mdx
index e69de29..281e133 100644
--- a/help-center/common-analyses/cohort-lto.mdx
+++ b/help-center/common-analyses/cohort-lto.mdx
@@ -0,0 +1,44 @@
+---
+title: "Cohort LTO analysis"
+description: "How to analyze lifetime orders (LTO) by cohort using SourceMedium tables and common filters"
+sidebarTitle: "Cohort LTO"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to analyze **lifetime orders (LTO)** by cohort (typically first order month) and understand which acquisition cohorts generate the most repeat purchasing.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Customers: [`obt_customers`](/data-activation/data-tables/sm_transformed_v2/obt_customers)
+- (Optional) Order lines: [`obt_order_lines`](/data-activation/data-tables/sm_transformed_v2/obt_order_lines)
+
+## Define the cohort
+
+Most commonly:
+
+1. Cohort grain: first order **month**
+2. Cohort key: customer’s **first valid purchase date** (using SourceMedium-valid orders)
+
+Tip: Keep cohort logic consistent with any LTV reporting you already use.
+
+## Build the analysis (high level)
+
+1. Filter to SourceMedium-valid orders (`is_order_sm_valid = TRUE`).
+2. Determine each customer’s cohort (first valid order date).
+3. For each cohort, compute:
+ - Total orders
+ - Distinct customers
+ - Average lifetime orders = `total orders / distinct customers`
+4. Add breakdowns (channel, product category, geography) only after the cohort math looks right.
+
+## Common pitfalls
+
+- Mixing invalid/test/refunded orders with valid orders (always start with `is_order_sm_valid = TRUE`).
+- Comparing cohorts with different “age” (newer cohorts haven’t had time to accumulate repeat purchases).
+- Blending channels (e.g., Amazon + Online DTC) when the question is channel-specific.
+
+## Next steps
+
+- Pair this with retention-focused analysis: [Customer retention](/help-center/common-analyses/customer-retention)
+- If you’re reconciling to Shopify: start with [Why don’t Executive Summary & Shopify match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
diff --git a/help-center/common-analyses/cohort-ltv.mdx b/help-center/common-analyses/cohort-ltv.mdx
index e69de29..ae5bf2b 100644
--- a/help-center/common-analyses/cohort-ltv.mdx
+++ b/help-center/common-analyses/cohort-ltv.mdx
@@ -0,0 +1,43 @@
+---
+title: "Cohort LTV analysis"
+description: "How to analyze customer lifetime value (LTV) by cohort using SourceMedium tables and common filters"
+sidebarTitle: "Cohort LTV"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to analyze **lifetime value (LTV)** by cohort (typically first purchase month) and compare cohort quality over time.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Customers: [`obt_customers`](/data-activation/data-tables/sm_transformed_v2/obt_customers)
+
+## Define LTV (before you chart)
+
+Decide which revenue definition you want to use consistently:
+
+- **Net revenue** (common for LTV): `order_net_revenue`
+- **Gross revenue**: `order_gross_revenue`
+
+If you include refunds/returns/cancellations, be explicit and keep the same definition across dashboards.
+
+## Build the analysis (high level)
+
+1. Filter to SourceMedium-valid orders (`is_order_sm_valid = TRUE`).
+2. Determine each customer’s cohort (first valid order date).
+3. For each cohort, compute:
+ - Total net revenue (or gross revenue)
+ - Distinct customers
+ - LTV = `total revenue / distinct customers`
+4. Add cohort aging (e.g., “months since cohort start”) if you want true cohort curves.
+
+## Common pitfalls
+
+- Comparing cohorts at different maturity (newer cohorts are incomplete).
+- Mixing revenue definitions when validating against other reports.
+- Not filtering out excluded/invalid orders.
+
+## Next steps
+
+- Pair with order behavior: [Cohort LTO](/help-center/common-analyses/cohort-lto)
+- If net revenue looks “off”, start here: [Why don’t Executive Summary & Shopify match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
diff --git a/help-center/common-analyses/common-analysis-template.mdx b/help-center/common-analyses/common-analysis-template.mdx
index 35333f4..826e9aa 100644
--- a/help-center/common-analyses/common-analysis-template.mdx
+++ b/help-center/common-analyses/common-analysis-template.mdx
@@ -1,9 +1,35 @@
---
title: 'Common Analysis Template'
-description: 'Longer-form version of title (REPLACE)'
+description: "A reusable structure for running analyses in SourceMedium: define the question, the metric, the grain, and the filters"
icon: 'magnifying-glass-location'
---
-
-
-
\ No newline at end of file
+Use this template when you’re not sure how to structure a question, or when you want to standardize analyses across stakeholders.
+
+## 1) Define the question
+
+Examples:
+
+- “Which cohorts have the highest LTV after 90 days?”
+- “Which products are most often purchased together?”
+- “Why did ROAS drop week over week?”
+
+## 2) Choose the primary metric
+
+Pick one metric to optimize the analysis around (revenue, orders, CPA, retention rate, etc.). Decide the revenue definition up front (gross vs net).
+
+## 3) Pick a grain and time window
+
+- Grain: day / week / month / customer / order / order line
+- Time window: last 30/90 days, QTD, by cohort month, etc.
+
+## 4) Apply the baseline filters
+
+Start with the “clean” baseline and only relax it intentionally:
+
+- `is_order_sm_valid = TRUE` (where applicable)
+- Focused channel selection if you’re comparing to a channel-specific source report
+
+## 5) Add one breakdown at a time
+
+Add dimensions one-by-one and validate after each step (channel → platform → campaign → creative).
diff --git a/help-center/common-analyses/customer-retention.mdx b/help-center/common-analyses/customer-retention.mdx
index e69de29..1dede93 100644
--- a/help-center/common-analyses/customer-retention.mdx
+++ b/help-center/common-analyses/customer-retention.mdx
@@ -0,0 +1,38 @@
+---
+title: "Customer retention analysis"
+description: "How to measure customer retention and repeat purchasing with SourceMedium tables and common filters"
+sidebarTitle: "Customer retention"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to understand how well you retain customers over time and where repeat purchasing comes from.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Customers: [`obt_customers`](/data-activation/data-tables/sm_transformed_v2/obt_customers)
+
+## Common retention cuts
+
+- New vs repeat customers over time
+- Repeat rate by acquisition channel
+- Time to second order (and distribution)
+- Retention by product purchased on first order
+
+## Suggested workflow
+
+1. Start with clean order filters:
+ - `is_order_sm_valid = TRUE`
+2. Decide whether to include all channels or a focused channel (e.g., Online DTC only).
+3. Pick a retention definition:
+ - “Customer retained” = places any additional valid order within X days
+ - Or “Repeat customer” = has `order_index >= 2`
+4. Break down by a single dimension (channel, first product, geography), validate, then layer on additional breakdowns.
+
+## Troubleshooting
+
+- If you see unexpected counts when reconciling, check for:
+ - Exclude $0 orders logic
+ - Channel mapping rules
+
+See also: [Why don’t Executive Summary & Shopify match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
diff --git a/help-center/common-analyses/revenue-retention.mdx b/help-center/common-analyses/revenue-retention.mdx
index e69de29..d56bc5d 100644
--- a/help-center/common-analyses/revenue-retention.mdx
+++ b/help-center/common-analyses/revenue-retention.mdx
@@ -0,0 +1,32 @@
+---
+title: "Revenue retention analysis"
+description: "How to measure revenue retention over time using SourceMedium tables and consistent revenue definitions"
+sidebarTitle: "Revenue retention"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to measure **how much revenue you retain** from existing customers over time.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Customers: [`obt_customers`](/data-activation/data-tables/sm_transformed_v2/obt_customers)
+
+## Define revenue retention (pick one)
+
+- **Gross revenue retention (GRR):** how much existing-customer revenue remains, excluding expansion
+- **Net revenue retention (NRR):** GRR + expansion from existing customers
+
+The exact definition depends on your business (subscription vs non-subscription). Write the definition down before you compute it.
+
+## Suggested workflow
+
+1. Filter to valid orders: `is_order_sm_valid = TRUE`.
+2. Choose a baseline window (e.g., customers who purchased in a given month).
+3. Track subsequent revenue from that same customer set across future periods.
+4. Segment by acquisition channel, first product, or subscription status to identify drivers.
+
+## Common pitfalls
+
+- Mixing subscription and one-time revenue in a single metric without clear separation.
+- Comparing cohorts at different maturity.
diff --git a/help-center/common-analyses/roas.mdx b/help-center/common-analyses/roas.mdx
index a5a4ddd..27583ea 100644
--- a/help-center/common-analyses/roas.mdx
+++ b/help-center/common-analyses/roas.mdx
@@ -1,7 +1,87 @@
---
-title: 'Return on Ad Spend'
-description: 'Understand your true return on adspend'
-icon: 'map'
+title: "Return on Ad Spend (ROAS)"
+description: "How to calculate, interpret, and analyze return on ad spend across channels using SourceMedium data"
+sidebarTitle: "ROAS"
+icon: "chart-line-up"
---
-Understanding your global -- as well as channel-level -- Return on Ad Spend
\ No newline at end of file
+Use this guide to understand **Return on Ad Spend (ROAS)** at global, channel, and campaign levels using SourceMedium data.
+
+## What is ROAS?
+
+ROAS measures the revenue generated for every dollar spent on advertising:
+
+```
+ROAS = Revenue / Ad Spend
+```
+
+A ROAS of 3.0 means you earned $3 in revenue for every $1 spent on ads.
+
+## Where to find ROAS in SourceMedium
+
+### Executive Summary
+The [Executive Summary module](/data-activation/managed-bi-v1/modules/executive-summary-module) shows global ROAS across all paid channels.
+
+### Marketing Overview
+The [Marketing Overview module](/data-activation/managed-bi-v1/modules/marketing-overview-module) breaks down ROAS by channel (Meta, Google, TikTok, etc.).
+
+### Ad Performance table
+For granular analysis, use [`rpt_ad_performance_daily`](/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily):
+- `ad_spend` — Total spend
+- `ad_platform_reported_revenue` — Revenue attributed to ads (as reported by the ad platform)
+- Calculate: `ad_platform_reported_revenue / ad_spend`
+
+## ROAS by attribution model
+
+You’ll see ROAS reflected in a few different ways depending on the view you’re using:
+
+- **Platform-reported ROAS:** best for reconciling to Meta/Google/TikTok reporting, using `rpt_ad_performance_daily` (spend and platform-reported revenue).
+- **Dashboard ROAS (blended / channel-level):** best for high-level planning, shown in Executive Summary and Marketing Overview.
+- **MTA ROAS (if enabled):** best for multi-touch analysis, covered in the MTA documentation.
+
+
+If your ROAS looks different from in-platform reporting, it's usually due to attribution windows or revenue definitions. See [attribution windows FAQ](/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms).
+
+
+## Common ROAS analyses
+
+### 1. Channel comparison
+Compare ROAS across channels to understand efficiency:
+- Which channels drive the best return?
+- Are you over-investing in low-ROAS channels?
+
+### 2. ROAS trends over time
+Track weekly/monthly ROAS trends:
+- Identify seasonal patterns
+- Spot declining efficiency early
+
+### 3. New vs returning customer ROAS
+If you have customer-level attribution:
+- What's your ROAS on prospecting (new customers)?
+- What's your ROAS on retargeting (returning customers)?
+
+## Interpreting ROAS
+
+| ROAS | Interpretation |
+|------|----------------|
+| < 1.0 | Losing money on ads (spend > revenue) |
+| 1.0 - 2.0 | Low efficiency; may not cover COGS/overhead |
+| 2.0 - 4.0 | Typical range for many DTC brands |
+| > 4.0 | Strong efficiency (validate it's not measurement error) |
+
+
+A high ROAS isn't always good — it may indicate under-investment in growth. Balance ROAS against total revenue and new customer acquisition.
+
+
+## Common pitfalls
+
+- **Comparing apples to oranges**: Platform-reported ROAS uses different attribution than SourceMedium's unified view.
+- **Ignoring attribution windows**: Different platforms use different default windows (e.g., Meta's 7-day click / 1-day view). Check your platform settings.
+- **Looking at ROAS in isolation**: Always pair with total spend and revenue — a 10x ROAS on $100 spend is less valuable than 3x ROAS on $10,000 spend.
+
+## Related resources
+
+- [Marketing Overview module](/data-activation/managed-bi-v1/modules/marketing-overview-module)
+- [Ad Performance table](/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily)
+- [Attribution windows FAQ](/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms)
+- [Contribution margin guide](/help-center/common-analyses/understanding-your-contribution-margin)
diff --git a/help-center/common-analyses/subscription-program-retention.mdx b/help-center/common-analyses/subscription-program-retention.mdx
index e69de29..669ea07 100644
--- a/help-center/common-analyses/subscription-program-retention.mdx
+++ b/help-center/common-analyses/subscription-program-retention.mdx
@@ -0,0 +1,28 @@
+---
+title: "Subscription program retention analysis"
+description: "How to analyze subscription retention and churn using SourceMedium tables and subscription signals"
+sidebarTitle: "Subscription retention"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to assess subscription retention/churn and how subscription customers behave compared to one-time customers.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Customers: [`obt_customers`](/data-activation/data-tables/sm_transformed_v2/obt_customers)
+
+## Key concepts
+
+- Subscription orders can be flagged in `obt_orders` (e.g., `is_subscription_order`, `is_order_recurring_subscription`).
+- If you’re validating against your subscription platform, start by aligning the definition of “active”, “new”, and “cancelled”.
+
+## Suggested workflow
+
+1. Filter to valid orders: `is_order_sm_valid = TRUE`.
+2. Segment subscription vs non-subscription customers.
+3. Analyze:
+ - Subscription order frequency
+ - Time between subscription orders
+ - Churn proxy (no subscription orders in X days)
+4. If you have a direct integration, reconcile key counts to the source platform.
diff --git a/help-center/common-analyses/top-converting-products.mdx b/help-center/common-analyses/top-converting-products.mdx
index e69de29..5b12eab 100644
--- a/help-center/common-analyses/top-converting-products.mdx
+++ b/help-center/common-analyses/top-converting-products.mdx
@@ -0,0 +1,27 @@
+---
+title: "Top converting products"
+description: "How to identify products that convert best using SourceMedium order and order line tables"
+sidebarTitle: "Top converting products"
+icon: "magnifying-glass-location"
+---
+
+Use this guide to find which products drive the most conversions and revenue, and how that changes by channel or acquisition source.
+
+## Recommended tables
+
+- Orders: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Order lines: [`obt_order_lines`](/data-activation/data-tables/sm_transformed_v2/obt_order_lines)
+
+## Suggested workflow
+
+1. Start with valid orders: `is_order_sm_valid = TRUE`.
+2. Use order lines to aggregate product performance:
+ - Orders containing product
+ - Net revenue attributed to product lines
+ - Quantity sold
+3. Add slices:
+ - Channel (`sm_channel`)
+ - New vs repeat customer
+ - Discounted vs non-discounted orders
+
+Tip: If you’re looking for funnel-stage conversion (views → add to cart → purchase), you’ll want funnel events tables instead of order lines.
diff --git a/help-center/common-analyses/top-selling-products.mdx b/help-center/common-analyses/top-selling-products.mdx
index b157ca0..42f07ca 100644
--- a/help-center/common-analyses/top-selling-products.mdx
+++ b/help-center/common-analyses/top-selling-products.mdx
@@ -1,6 +1,26 @@
---
title: 'Top Selling Products'
-description: 'placeholder'
+description: "How to identify your top-selling products by revenue, orders, and quantity using SourceMedium order line data"
icon: 'star'
---
-asdfas df
\ No newline at end of file
+
+Use this guide to find your top-selling products and understand how product performance changes by channel and customer type.
+
+## Recommended tables
+
+- Order lines: [`obt_order_lines`](/data-activation/data-tables/sm_transformed_v2/obt_order_lines)
+- Orders (for filtering/segmentation): [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
+## Suggested workflow
+
+1. Filter to valid orders (`is_order_sm_valid = TRUE`).
+2. Aggregate by product (and optionally variant) to compute:
+ - Orders containing product
+ - Quantity sold
+ - Net revenue
+3. Add slices:
+ - Channel (`sm_channel`)
+ - New vs repeat
+ - Discount codes
+
+Tip: If you want “top converting” vs “top selling”, start from funnel events rather than order lines.
diff --git a/help-center/common-analyses/understanding-your-contribution-margin.mdx b/help-center/common-analyses/understanding-your-contribution-margin.mdx
index 73e36a2..0f7eb79 100644
--- a/help-center/common-analyses/understanding-your-contribution-margin.mdx
+++ b/help-center/common-analyses/understanding-your-contribution-margin.mdx
@@ -1,4 +1,29 @@
---
title: "Understanding your Contribution Margin"
+description: "How contribution margin is calculated, which variable costs it includes, and common validation steps"
icon: 'dollar-sign'
----
\ No newline at end of file
+---
+
+Contribution margin extends gross profit by including additional variable costs that scale with demand (for example, marketing spend).
+
+## What it represents
+
+Contribution margin answers: “After variable costs, how much do we have left to cover fixed costs and profit?”
+
+Depending on your definition, it may include:
+
+- Gross profit components (COGS + fulfillment + fees, etc.)
+- Marketing spend (paid media + other variable acquisition costs)
+- Other variable operating expenses (if modeled)
+
+## Where to look in SourceMedium
+
+- Marketing spend: [`rpt_ad_performance_daily`](/data-activation/data-tables/sm_transformed_v2/rpt_ad_performance_daily) (and/or configuration sheet spend inputs)
+- Blended order profitability: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
+## Troubleshooting
+
+If contribution margin is unexpected:
+
+- Confirm which spend sources are included (integrations vs config sheet)
+- Confirm refunds/cancellations and the revenue definition used
diff --git a/help-center/common-analyses/understanding-your-gross-profit.mdx b/help-center/common-analyses/understanding-your-gross-profit.mdx
index edd0368..454e3b6 100644
--- a/help-center/common-analyses/understanding-your-gross-profit.mdx
+++ b/help-center/common-analyses/understanding-your-gross-profit.mdx
@@ -1,4 +1,32 @@
---
title: "Understanding your Gross Profit"
+description: "How gross profit is calculated, which costs it includes, and where to validate inputs in SourceMedium"
icon: 'dollar-sign'
----
\ No newline at end of file
+---
+
+Gross profit helps you understand how much profit you generate after accounting for the variable costs required to sell and fulfill an order.
+
+## Common components
+
+Gross profit is typically derived from:
+
+- Net revenue (after discounts and refunds)
+- Minus product costs (COGS)
+- Minus fulfillment costs
+- Minus shipping costs (if modeled as a cost component)
+- Minus merchant processing fees
+
+## Where to look in SourceMedium
+
+- Order-level profitability: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- Ensure cost inputs are present and up to date:
+ - [Product costs](/help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs)
+ - [Fulfillment costs](/help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs)
+ - [Merchant processing fees](/help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees)
+
+## Troubleshooting
+
+If gross profit looks “off”, confirm:
+
+- You’re using the same revenue definition across tools (gross vs net)
+- Costs are populated for the same date range and channels
diff --git a/help-center/core-concepts/attribution/attribution-in-sourcemedium.mdx b/help-center/core-concepts/attribution/attribution-in-sourcemedium.mdx
index e69de29..b40d4a8 100644
--- a/help-center/core-concepts/attribution/attribution-in-sourcemedium.mdx
+++ b/help-center/core-concepts/attribution/attribution-in-sourcemedium.mdx
@@ -0,0 +1,55 @@
+---
+title: "Attribution in SourceMedium"
+description: "How SourceMedium uses UTMs and attribution models (last-click and MTA) to attribute orders and revenue"
+sidebarTitle: "Attribution"
+icon: "sitemap"
+---
+
+SourceMedium supports multiple attribution approaches. This guide explains what we mean by attribution, where it comes from, and which knobs typically cause differences between tools.
+
+## Two common attribution layers
+
+### Last-click attribution (UTM-based)
+
+Last-click attribution assigns credit to the **most recent** tracked marketing touch before a purchase.
+
+- Primary inputs: UTM parameters, landing pages, referrers
+- Common use: channel reporting, performance trends, and reconciliation to analytics tools
+
+Related docs:
+
+- [UTM setup](/help-center/core-concepts/attribution/utm-setup)
+- [What is last-click attribution?](/help-center/faq/account-management-faqs/what-is-last-click-attribution)
+- [How can I improve my last-click attribution?](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution)
+- [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy) - How we prioritize between data sources
+
+### Multi-touch attribution (MTA)
+
+Multi-touch attribution assigns credit across multiple touch points within a lookback window.
+
+- Primary inputs: first-party event streams (e.g., GA4), marketing data, and modeled purchase journeys
+- Common use: understanding incremental contribution across channels, creatives, and landing pages
+
+Related docs:
+
+- [First-party attribution](/help-center/core-concepts/attribution/first-party-attribution)
+- [MTA overview](/mta/mta-overview)
+- [MTA FAQs](/mta/mta-faqs)
+
+### Zero-party attribution (survey-based)
+
+Zero-party attribution uses **customer-reported** survey answers (for example: “How did you hear about us?”) to understand top-of-funnel discovery that tracking often misses.
+
+Related docs:
+
+- [Zero-party attribution](/help-center/core-concepts/attribution/zero-party-attribution)
+- [Survey best practices (HDYHAU)](/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey)
+
+## Common reasons attribution differs between tools
+
+- Different lookback windows (e.g., 7-day vs 28-day vs 120-day)
+- Missing or inconsistent UTMs (especially for email/SMS and paid social)
+- Cross-domain or checkout tracking limitations
+- Post-purchase edits or delayed revenue recognition
+
+If you’re reconciling against Shopify, start with: [Why don’t Executive Summary & Shopify match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
diff --git a/help-center/core-concepts/attribution/direct-none.mdx b/help-center/core-concepts/attribution/direct-none.mdx
new file mode 100644
index 0000000..8ac3fb5
--- /dev/null
+++ b/help-center/core-concepts/attribution/direct-none.mdx
@@ -0,0 +1,63 @@
+---
+title: "Why am I seeing (direct) / (none)?"
+sidebarTitle: "(direct) / (none)"
+description: "Understand what (direct)/(none) means in attribution reporting and how to diagnose and reduce it"
+icon: "heart-pulse"
+---
+
+In attribution reporting, **`(direct) / (none)`** typically means SourceMedium could not confidently associate an order with a marketing touchpoint (for example, missing UTMs or lost attribution context during the journey).
+
+## Common causes
+
+1. **Missing UTMs**: Campaigns (especially email/SMS and paid social) aren't consistently tagged.
+2. **UTMs dropped during the journey**: Cross-domain transitions, checkout flows, or redirects (including URL shorteners and 302s) lose parameters.
+3. **"Dark social" and mobile apps**: Links shared via WhatsApp, Slack, SMS, or clicked within mobile apps often don't pass referrer data.
+4. **Offline documents**: Links embedded in PDFs, Word/Excel/PowerPoint files, or slide decks have no referrer context.
+5. **HTTPS to HTTP transitions**: Navigating from a secure site to a non-secure page drops referral data for security.
+6. **Tracking blockers**: Ad blockers, iOS privacy restrictions, browser privacy modes, and firewall settings reduce client-side capture.
+7. **Bookmarks and direct URL entry**: Returning customers who bookmarked your site or type the URL directly.
+8. **Long time-to-convert**: The purchase happens after attribution context expires or can't be stitched.
+
+## How to diagnose (fast)
+
+
+
+ Pick a few live campaigns and click through. Confirm the landing page URL includes `utm_source` / `utm_medium` / `utm_campaign`.
+
+
+ If the landing page has UTMs but orders still show `(direct) / (none)`, the drop often happens during cross-domain navigation or checkout.
+
+
+ If `(direct) / (none)` spikes after a specific campaign type (email/SMS, paid social, affiliates), that’s usually the tagging or redirect path for that channel.
+
+
+ If surveys show meaningful discovery but tracking shows `(direct) / (none)`, that’s a strong signal you have a capture gap.
+
+
+
+## How to reduce (direct) / (none)
+
+- Standardize UTM tagging across all channels (start here: [UTM Setup](/help-center/core-concepts/attribution/utm-setup))
+- Add server-side/checkout capture for platforms where UTMs are commonly dropped (Shopify Plus teams often capture UTMs into order attributes)
+- Use post-purchase surveys to supplement tracking-based attribution for offline and hard-to-track channels
+
+## Related resources
+
+
+
+ Tag links consistently so last-click attribution stays reliable.
+
+
+ A structured toolkit for diagnosing and fixing attribution gaps.
+
+
+ Shopify Plus developer guide for capturing UTMs at checkout.
+
+
+ Use surveys to capture discovery channels tracking can’t see.
+
+
+
+
+For a deeper dive into debugging this in GA4, check out Google's guide on [Traffic acquisition reports](https://support.google.com/analytics/answer/9143382).
+
diff --git a/help-center/core-concepts/attribution/first-party-attribution.mdx b/help-center/core-concepts/attribution/first-party-attribution.mdx
new file mode 100644
index 0000000..340162f
--- /dev/null
+++ b/help-center/core-concepts/attribution/first-party-attribution.mdx
@@ -0,0 +1,69 @@
+---
+title: "What is first-party attribution?"
+sidebarTitle: "First-Party Attribution"
+description: "Understand first-party attribution, what first-party signals SourceMedium uses, and how it relates to last-click and MTA"
+icon: "shield"
+---
+
+**First-party attribution** uses data you collect and control from your own properties (your site/app and checkout) to understand which marketing touchpoints contributed to purchases.
+
+In practice, this typically includes **First-Party Inputs** from multiple sources:
+- **Website Events**: pixel-based tracking (e.g., GA4, Elevar)
+- **Server-Side Capture**: API-based tracking (e.g., Shopify Order Attributes, Connectors)
+- **Landing Page Data**: Referrer and URL parameters captured at the start of the session
+
+SourceMedium aggregates all these *First-Party Inputs* to build a complete picture.
+
+## First-party vs platform-reported attribution
+
+- **First-party**: derived from your site/app + checkout signals (what happened on your properties)
+- **Platform-reported**: derived from ad platforms (what platforms believe happened based on their measurement and models)
+
+Both can be useful; they often differ due to attribution windows, privacy restrictions, and identity resolution.
+
+## What counts as a first-party signal in SourceMedium
+
+Common examples include:
+
+- Website analytics/event streams (e.g., GA4, Elevar)
+- Landing page + referrer capture (including UTMs when present)
+- Checkout/order-level capture for UTMs (useful when browser tracking drops parameters)
+
+## Where first-party attribution shows up in SourceMedium
+
+- **Last-click attribution (UTM-based)**: relies on UTMs/landing/referrer capture to assign the most recent touchpoint.
+- **Multi-touch attribution (MTA)**: uses first-party purchase journeys (touchpoints) to model first touch, last touch, and linear attribution across the journey.
+
+## Common failure modes (and how to reduce them)
+
+- **`(direct) / (none)` growth**: usually missing UTMs or UTMs being dropped during the journey (cross-domain/checkout).
+- **Cross-domain/checkout breaks**: customers move between domains or checkout flows and attribution context is lost.
+- **Browser/privacy restrictions**: ad blockers, iOS privacy features, and browser changes reduce client-side tracking reliability.
+
+
+Start with consistent UTM setup, then ensure you are capturing data across both client-side (pixel) and server-side (API) inputs to maximize coverage.
+
+
+## External resources
+
+- [Shopify Checkout UI Extensions](https://shopify.dev/docs/api/checkout-ui-extensions) — For building server-side UTM capture (Shopify Plus)
+
+## Related resources
+
+
+
+ What UTMs are and how to implement them across channels.
+
+
+ Find and fix tracking gaps that reduce first-party coverage.
+
+
+ How SourceMedium builds multi-touch attribution from first-party purchase journeys.
+
+
+ Troubleshoot common analytics issues that impact event-based attribution.
+
+
+ Shopify Plus developer guide for capturing UTMs at checkout.
+
+
diff --git a/help-center/core-concepts/attribution/utm-setup.mdx b/help-center/core-concepts/attribution/utm-setup.mdx
new file mode 100644
index 0000000..2187147
--- /dev/null
+++ b/help-center/core-concepts/attribution/utm-setup.mdx
@@ -0,0 +1,172 @@
+---
+title: "What are UTMs (and how to set them up)?"
+sidebarTitle: "UTM Setup"
+description: "Learn what UTM parameters are, how to name them, and how to set them up for reliable last-click attribution"
+icon: "bullseye"
+---
+
+UTM parameters (Urchin Tracking Module) are **query string parameters** you add to links so tools like SourceMedium and Google Analytics can attribute visits and purchases back to marketing campaigns.
+
+## How UTMs work (in practice)
+
+- UTMs are appended to a URL (after a `?`).
+- When a user clicks that URL, analytics tools record those parameters for the visit/session.
+- When the user purchases, SourceMedium uses the available attribution signals (including UTMs) to assign attribution (see [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy)).
+
+## The UTM fields (and what they mean)
+
+SourceMedium primarily uses these fields:
+
+- `utm_source`: **Where** the traffic came from (e.g., `google`, `meta`, `klaviyo`, `podcast_partner`)
+- `utm_medium`: **How** it got there (e.g., `cpc`, `paid_social`, `email`, `affiliate`)
+- `utm_campaign`: **Which campaign** (e.g., `bfcm_2025`, `spring_launch`)
+- `utm_content`: Optional creative/variation (e.g., `video_15s`, `carousel_a`)
+- `utm_term`: Optional keyword/targeting (often paid search)
+- `utm_id`: Optional internal campaign identifier
+
+
+If you’re starting from scratch, make `utm_source`, `utm_medium`, and `utm_campaign` mandatory. Use `utm_content` and `utm_term` only when you’ll actively use them.
+
+
+## What each value should represent
+
+Here’s a practical mental model that prevents messy reporting:
+
+- Put the **platform/publisher** in `utm_source` (where the traffic is coming from)
+- Put the **marketing motion** in `utm_medium` (how you’re buying/sending it)
+- Put the **initiative** in `utm_campaign` (what you’re running)
+- Put the **creative/variation** in `utm_content` (what version)
+
+
+Avoid putting highly-granular values (like ad IDs) in `utm_source` or `utm_medium`. Those tend to explode your reporting into thousands of rows.
+
+
+## Recommended naming conventions
+
+Consistency matters more than the “perfect” taxonomy. Pick rules your team will actually follow.
+
+**Recommended defaults**
+- Lowercase values (avoid `Facebook` vs `facebook`)
+- Use `_` for separators (avoid spaces)
+- Keep sources stable over time (campaigns can change; sources shouldn’t)
+
+**Example**
+```text
+https://example.com/products/widget?utm_source=meta&utm_medium=paid_social&utm_campaign=spring_launch&utm_content=video_15s
+```
+
+## How to tag links (step-by-step)
+
+1. Start from the clean destination URL (no UTMs).
+2. Use the official [Google Campaign URL Builder](https://ga-dev-tools.google/ga4/campaign-url-builder/) to ensure correct formatting.
+3. Decide values for `utm_source`, `utm_medium`, `utm_campaign` (and optionally `utm_content`, `utm_term`).
+4. Append parameters to the URL:
+ - If the URL has no query params, start with `?utm_source=...`
+ - If it already has query params, append with `&utm_source=...`
+5. Click your own tagged link and confirm the landing page retains UTMs.
+6. Reuse the same conventions everywhere (ads, emails, affiliates, QR codes).
+
+
+If you use short links, ensure the short link resolves to a URL that still includes the UTMs (or preserves them via redirect).
+
+
+## Setup checklist (by channel)
+
+
+
+ Ensure every ad destination URL has UTMs. If the platform supports templates, use a single template so your whole account stays consistent.
+
+
+ Tag final URLs with UTMs. If you use auto-tagging (click IDs), still set UTMs for human-readable reporting.
+
+
+ Tag every link, including buttons and image links. Email/SMS is a common source of `(direct) / (none)` if links aren’t consistently tagged.
+
+
+ Give each partner a tagged URL (or short link that redirects to a tagged URL). Decide whether you want partner-level detail in `utm_source` or `utm_content`.
+
+
+ Use tagged vanity URLs/QR codes that redirect to your UTM-tagged landing page. Pair with a post-purchase survey to validate discovery.
+
+
+
+## Examples (copy/paste)
+
+**Paid social ad**
+```text
+https://example.com/collections/new?utm_source=meta&utm_medium=paid_social&utm_campaign=spring_launch&utm_content=carousel_a
+```
+
+**Paid search**
+```text
+https://example.com/products/widget?utm_source=google&utm_medium=cpc&utm_campaign=brand_search&utm_term=widget
+```
+
+**Email**
+```text
+https://example.com/pages/sale?utm_source=klaviyo&utm_medium=email&utm_campaign=bfcm_2025&utm_content=hero_button
+```
+
+**Influencer**
+```text
+https://example.com/discount/CREATOR?utm_source=creator_name&utm_medium=influencer&utm_campaign=creator_program
+```
+
+## Standard Channel Groupings
+
+Adopting a standard taxonomy helps ensure your data maps correctly to channels in SourceMedium and Google Analytics.
+
+| Channel | `utm_source` | `utm_medium` |
+| :--- | :--- | :--- |
+| **Paid Social** | `facebook`, `instagram`, `tiktok` | `paid_social`, `cpc` |
+| **Paid Search** | `google`, `bing` | `cpc`, `paid_search` |
+| **Email** | `klaviyo`, `mailchimp` | `email` |
+| **SMS** | `attentive`, `postscript` | `sms` |
+| **Affiliate** | `shareasale`, `impact` | `affiliate` |
+| **Organic Social** | `instagram`, `tiktok`, `youtube` | `social`, `organic` |
+
+## QA: how to verify UTMs are working
+
+1. Click a test link with UTMs and confirm the landing page URL includes the UTM parameters.
+2. Add a product and proceed to checkout; confirm UTMs aren’t dropped during the journey (cross-domain and checkout flows are common break points).
+3. In SourceMedium, spot-check recent orders to confirm expected `utm_source` / `utm_medium` values appear (and aren’t falling back to `(direct) / (none)`).
+
+
+If checkout or privacy features drop UTMs, Shopify Plus teams often add a server-side backup by capturing UTMs into order attributes at checkout.
+
+
+## Common mistakes (and how to avoid them)
+
+- **Inconsistent casing** (`Meta` vs `meta`) → standardize to lowercase
+- **Overlapping meanings** (`utm_source=paid_social`) → keep `source` for the platform, `medium` for the motion
+- **Untagged email/SMS links** → tag all links (buttons + images), not just one CTA
+- **Changing conventions mid-stream** → don’t rename sources/mediums without a migration plan (reporting will split)
+
+## UTMs vs click IDs (gclid, fbclid, etc.)
+
+Click IDs can help identify an ad click, but they don’t replace a consistent UTM taxonomy. In SourceMedium, click IDs can act as a **fallback-only inference** for the channel-level source when explicit UTMs are missing.
+
+## External resources
+
+- [Google Campaign URL Builder](https://ga-dev-tools.google/ga4/campaign-url-builder/) — Official tool for generating tagged URLs
+- [Google Analytics: Custom URL collection](https://support.google.com/analytics/answer/10917952) — Google's official UTM documentation
+
+## Related resources
+
+
+
+ How UTM-based last-click attribution works in SourceMedium.
+
+
+ Practical best practices and common pitfalls.
+
+
+ How SourceMedium selects the winning source when multiple signals exist.
+
+
+ Diagnose common attribution gaps like `(direct) / (none)`.
+
+
+ Developer guide for Shopify order-attribute capture and backfills.
+
+
diff --git a/help-center/core-concepts/attribution/zero-party-attribution.mdx b/help-center/core-concepts/attribution/zero-party-attribution.mdx
new file mode 100644
index 0000000..62d1b70
--- /dev/null
+++ b/help-center/core-concepts/attribution/zero-party-attribution.mdx
@@ -0,0 +1,65 @@
+---
+title: "What is zero-party attribution?"
+sidebarTitle: "Zero-Party Attribution"
+description: "Learn how customer-reported survey answers complement tracking-based attribution and how to use zero-party data in SourceMedium"
+icon: "square-poll-vertical"
+---
+
+**Zero-party attribution** is attribution based on what customers explicitly tell you—most commonly via a post-purchase survey like **"How did you hear about us?" (HDYHAU)**.
+
+
+The term "zero-party data" was coined by [Forrester Research](https://www.forrester.com/blogs/straight-from-the-source-collecting-zero-party-data-from-customers/): *"data that a customer intentionally and proactively shares with a brand, including preference center data, purchase intentions, and personal context."*
+
+
+This distinction is important:
+- **First-party data** is data you collect about a user's behavior (observed intent - e.g., "User viewed Blue Shirt").
+- **Zero-party data** is data the user tells you about themselves (explicit intent - e.g., "I am looking for a Blue Shirt").
+
+This complements tracking-based attribution by capturing discovery channels that are often hard to measure with cookies and pixels. As privacy restrictions reduce tracking reliability, zero-party data becomes increasingly valuable.
+
+## When zero-party attribution is most useful
+
+Zero-party data is especially valuable for:
+
+- Word of mouth / referrals
+- Podcasts, radio, print, and other offline media
+- Influencers where click tracking is inconsistent
+- PR and partnerships
+
+## How it fits with UTMs and MTA
+
+A simple way to think about the three layers:
+
+1. **Zero-party**: “How did you first hear about us?” (discovery/awareness)
+2. **UTM last-click**: the last tracked touch before purchase (conversion)
+3. **MTA**: credit across multiple touchpoints in the journey (multi-touch)
+
+
+If surveys show meaningful revenue from a channel that tracking doesn’t capture, treat that as a measurement gap to investigate—not just a reporting difference.
+
+
+## Survey setup basics (high impact)
+
+- Prefer **single-select** answers for clean reporting, with an optional free-text “Other”.
+- Keep options mutually exclusive (avoid overlapping choices like “Instagram” and “Social”).
+- Use stable naming for options so historical reporting stays consistent.
+
+## Related resources
+
+
+
+ How to design and deploy an effective post-purchase survey.
+
+
+ How zero-party attribution appears in SourceMedium reporting.
+
+
+ Set up Fairing for automated survey collection and order tagging.
+
+
+ Set up KnoCommerce for zero-party data collection and attribution.
+
+
+ How tracking-based signals complement self-reported discovery.
+
+
diff --git a/help-center/core-concepts/customer-record-enrichment/index.mdx b/help-center/core-concepts/customer-record-enrichment/index.mdx
new file mode 100644
index 0000000..5e8c565
--- /dev/null
+++ b/help-center/core-concepts/customer-record-enrichment/index.mdx
@@ -0,0 +1,80 @@
+---
+title: "Customer Record Enrichment (CDP Foundations)"
+sidebarTitle: "Customer Record"
+description: "How SourceMedium can be your customer source of truth for enrichment and audience workflows."
+icon: "users"
+---
+
+SourceMedium’s transformed dataset is designed to be a **central source of truth for your customers**—with stable join keys and normalized tables that make it easier to:
+- Build a customer 360 (orders, products, geo, acquisition context)
+- Attach enrichment fields (zero-party, first-party, or third-party)
+- Create audience-ready customer lists (while respecting privacy requirements)
+
+## What “customer record enrichment” means in practice
+
+Most enrichment work comes down to two steps:
+1. **Pick a customer-level join key** (usually `sm_customer_key`)
+2. **Attach attributes** you want to analyze (or activate) at the customer level
+
+In SourceMedium, `your_project.sm_transformed_v2.dim_customers` is the base customer table, and most downstream analysis joins back through `sm_customer_key`.
+
+## Common enrichment sources
+
+### Zero-party (self-reported)
+
+Collected directly from customers (post-purchase surveys, quizzes, account creation). This is typically the highest-quality demographic data you can get—because it’s explicit.
+
+### First-party (internal systems you control)
+
+Attributes you collect operationally (loyalty tier, VIP status, subscription preferences, customer tags) that can flow into the warehouse via customer/order tags or platform fields.
+
+### Third-party enrichment
+
+Purchased demographic/household attributes joined to your customer records via privacy-safe identifiers (often hashed email) or address/phone, depending on the vendor.
+
+### Inference (use cautiously)
+
+Heuristic enrichment derived from PII (for example, gender inference from first name). Useful for directional analysis, not ground truth.
+
+## Audience building workflows (warehouse-first)
+
+Once attributes are on a customer-level table, you can build segments like:
+- High LTV customers in a specific region
+- New customers acquired from a specific campaign strategy
+- Customers who match a survey persona
+
+Those segments can then be exported from your warehouse (commonly using hashed identifiers like `customer_email_hashed`) for downstream activation—if your policies and tools allow.
+
+### Strategy-based “audience” segments via campaign/UTM conventions
+
+If you run demographic-targeted (or persona-targeted) campaigns, the most reliable way to measure **long-term LTV** is to encode the targeting strategy into a joinable attribute at purchase time—typically UTMs.
+
+For example:
+- Create distinct ad sets per segment
+- Add a stable segment label to `utm_campaign` / `utm_content` / `utm_term`
+- Analyze LTV by that label in the warehouse
+
+This produces “LTV by targeting strategy” (joinable to customers/orders), which is usually more actionable than ad-platform demographic breakdowns.
+
+
+Be careful with PII and inferred demographic attributes. Ensure your privacy policy, consent practices, and downstream usage are compliant with applicable laws and platform policies.
+
+
+## Start here: demographics and joinability
+
+The most common question is demographics (age/gender) and whether ad platforms can provide it in a way that supports LTV.
+
+
+
+ What you can (and can’t) do for LTV by demographic
+
+
+ Practical tagging patterns for enrichment
+
+
+ Customer join keys and identity fields
+
+
+ How enrichment fits into SourceMedium’s transformation layer
+
+
diff --git a/help-center/core-concepts/data-definitions/channel-mapping.mdx b/help-center/core-concepts/data-definitions/channel-mapping.mdx
new file mode 100644
index 0000000..c36f1d6
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/channel-mapping.mdx
@@ -0,0 +1,55 @@
+---
+title: "Channel Mapping (sm_channel + sm_sub_channel)"
+description: "How SourceMedium assigns sm_channel and sm_sub_channel, including overrides and debugging."
+sidebarTitle: "Channel Mapping"
+icon: "map"
+---
+
+`sm_channel` is one of the highest-impact dimensions in SourceMedium. It controls how orders roll up into dashboards and many Query Library recipes.
+
+If you see “too many orders in online_dtc” or “TikTok Shop isn’t separated”, it’s usually a channel mapping issue (or missing override rules).
+
+## What gets mapped
+
+Key fields:
+- `sm_channel`: primary channel classification
+- `sm_sub_channel`: optional secondary breakdown
+- `sm_default_channel`: the fallback channel that would apply if no override rules match
+- `sm_order_sales_channel`: source-system sales channel (when available) used as an input to mapping
+
+## Override inputs (high level)
+
+Channel mapping rules can evaluate signals like:
+- UTMs (source/medium/campaign)
+- Order tags
+- Discount codes
+- SKUs
+- Shopify sales channel / order source
+
+## Sales channel specific overrides
+
+For Shopify orders, SourceMedium can expose Shopify’s sales channel (e.g., `pos`, `TikTok Shop`, `Instagram`, `Shop App`) as an additional mapping input.
+This enables rules like “map POS orders to retail” or “map TikTok Shop via Shopify to a separate channel”.
+
+## Where to start
+
+- For the full channel-value list and the priority hierarchy, see [Sales Channel (sm_channel)](/data-transformations/order-segmentation/sales-channel).
+- For “how do I create or override channels?”, see [Create Custom Channel Mappings](/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels).
+
+## Quick debugging query
+
+```sql
+SELECT
+ sm_order_key,
+ sm_channel,
+ sm_sub_channel,
+ sm_default_channel,
+ sm_order_sales_channel,
+ source_system_sales_channel,
+ sm_utm_source_medium
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= DATETIME_SUB(CURRENT_DATETIME(), INTERVAL 30 DAY)
+ORDER BY order_processed_at_local_datetime DESC
+LIMIT 200;
+```
diff --git a/help-center/core-concepts/data-definitions/event-and-journey-deduping.mdx b/help-center/core-concepts/data-definitions/event-and-journey-deduping.mdx
new file mode 100644
index 0000000..d628a2f
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/event-and-journey-deduping.mdx
@@ -0,0 +1,51 @@
+---
+title: "Event + Journey Deduping"
+description: "How SourceMedium prevents double-counting when multiple event streams exist, and what “multi-source dedupe” means."
+sidebarTitle: "Event + Journey Deduping"
+icon: "fingerprint"
+---
+
+Some brands have multiple event sources (GA4, Snowplow, Heap, Elevar, Blotout, etc.). Those sources can record the *same* touchpoint within seconds of each other, creating the risk of double-counting.
+
+For multi-source customers, SourceMedium uses **deduplication rules** to merge streams into a canonical view that preserves richness while preventing over-counting.
+
+## High-level approach
+
+For multi-source data, we consider touchpoints duplicates when core attributes match within a small time window. The dedupe fingerprint typically includes:
+- Timestamp (rounded to seconds, in UTC)
+- Standardized event name
+- UTM source / medium / campaign (with NULL normalized)
+
+Fields like `utm_content`, `utm_term`, and click IDs are preserved as enrichment but don’t always participate in the fingerprint (so you can still do creative-level analysis without inflating counts).
+
+## Where this shows up
+
+These patterns are most relevant when you query MTA / journey tables, like:
+- `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+
+## Recommended analysis patterns
+
+### Verify you’re not double-counting purchases
+```sql
+SELECT
+ COUNT(DISTINCT purchase_order_id) AS distinct_orders,
+ COUNTIF(sm_event_name = 'purchase') AS purchase_event_rows
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE event_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
+```
+
+### Compare touchpoint volumes by source system
+```sql
+SELECT
+ COALESCE(NULLIF(LOWER(TRIM(source_system)), ''), '(unknown)') AS source_system,
+ COUNT(*) AS touchpoints
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE event_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
+GROUP BY 1
+ORDER BY touchpoints DESC;
+```
+
+
+Single-source customers should remain unchanged; multi-source dedupe is only applied when multiple sources exist for the same order/journey.
+
+
diff --git a/help-center/core-concepts/data-definitions/index.mdx b/help-center/core-concepts/data-definitions/index.mdx
new file mode 100644
index 0000000..41d2154
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/index.mdx
@@ -0,0 +1,39 @@
+---
+title: "Data Definitions"
+description: "Canonical definitions for the fields and business rules that show up across SourceMedium tables, dashboards, and recipes."
+sidebarTitle: "Data Definitions"
+icon: "book-open"
+---
+
+These pages document the **definitions that matter** across SourceMedium:
+
+- The fields that appear across many tables (and therefore many dashboards + recipes)
+- The business rules behind how we normalize, map, and dedupe data
+- The “gotchas” that most often cause analysis to drift
+
+If you’re here for SQL examples, the fastest starting point is the [SQL Query Library](/data-activation/template-resources/sql-query-library).
+
+
+
+ How to filter orders correctly using `is_order_sm_valid`.
+
+
+ Net vs gross vs total revenue (and how refunds/discounts flow through).
+
+
+ Refund components, sign conventions, and common refund-rate patterns.
+
+
+ Subscription classification fields and “first vs recurring” flags.
+
+
+ How `sm_channel` and `sm_sub_channel` are assigned (and how overrides work).
+
+
+ How UTM fields are normalized and how to query them safely.
+
+
+ How we avoid double-counting when multiple event streams exist.
+
+
+
diff --git a/help-center/core-concepts/data-definitions/is-order-sm-valid.mdx b/help-center/core-concepts/data-definitions/is-order-sm-valid.mdx
new file mode 100644
index 0000000..274d5d5
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/is-order-sm-valid.mdx
@@ -0,0 +1,45 @@
+---
+title: "Valid Orders (is_order_sm_valid)"
+description: "What is_order_sm_valid means, why it matters, and how to use it correctly in queries."
+sidebarTitle: "Valid Orders"
+icon: "shield-check"
+---
+
+`is_order_sm_valid` is the **primary filter** for order-based analysis. It tells you whether an order should be included in reporting.
+
+
+If you’re querying any order-based table (`obt_orders`, `obt_order_lines`, or most `rpt_*` revenue tables), start with:
+`WHERE is_order_sm_valid = TRUE`.
+
+
+## What it means
+
+At a high level:
+- `TRUE`: include the order in revenue / order-count reporting
+- `FALSE`: exclude the order (e.g., cancelled/voided/draft/uncollectible and other non-reportable states)
+
+SourceMedium computes this at the order-line level and rolls it up to orders, so an order is considered valid if it has at least one valid order line.
+
+## Why it matters
+
+Most “why don’t my numbers match” issues come from one of these:
+- Missing the `is_order_sm_valid = TRUE` filter
+- Mixing valid + invalid orders across joined tables
+- Comparing valid-order metrics to external exports that include cancelled/test orders
+
+## Recommended query pattern
+
+```sql
+SELECT
+ COUNT(*) AS valid_order_count,
+ SUM(order_net_revenue) AS net_revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
+```
+
+## Related resources
+
+- [SQL Query Library](/data-activation/template-resources/sql-query-library)
+- [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
diff --git a/help-center/core-concepts/data-definitions/refund-logic.mdx b/help-center/core-concepts/data-definitions/refund-logic.mdx
new file mode 100644
index 0000000..c3dc8cd
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/refund-logic.mdx
@@ -0,0 +1,65 @@
+---
+title: "Refund Logic"
+description: "Refund fields, components, and best-practice refund analysis patterns."
+sidebarTitle: "Refund Logic"
+icon: "arrow-uturn-left"
+---
+
+Refunds can hit multiple components of an order (items, shipping, taxes, duties). SourceMedium tracks these separately so you can build accurate refund-rate and profitability analysis.
+
+## Core refund fields (order-level)
+
+In `your_project.sm_transformed_v2.obt_orders` you’ll commonly see:
+- `order_refunds`: item-level refunds
+- `order_shipping_refunds`: shipping refunds
+- `order_tax_refunds`: tax refunds (not shipping tax)
+- `order_shipping_tax_refunds`: shipping tax refunds
+- `order_duty_refunds`: duty refunds (when applicable)
+- `order_total_refunds`: order refunds + shipping refunds
+
+Refund timing fields include:
+- `earliest_order_refund_date`
+- `latest_order_refund_date`
+- `order_to_refund_days_earliest` / `_latest` (clamped to `0` for rare timing edge cases)
+
+## Sign convention
+
+Refund fields are intended to be **negative (or zero)** in most reporting tables. That makes netting behavior consistent:
+- Add refunds to subtract revenue
+- Sum refunds to get “refunds as a negative number”
+
+## Common patterns
+
+### Refund rate (revenue-weighted)
+```sql
+SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), WEEK(MONDAY)) AS week_start,
+ SUM(order_gross_revenue) AS gross_revenue,
+ SUM(order_refunds) AS refunds,
+ SAFE_DIVIDE(ABS(SUM(order_refunds)), NULLIF(SUM(order_gross_revenue), 0)) AS refund_rate
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
+GROUP BY 1
+ORDER BY week_start DESC;
+```
+
+### Identify “over-refunded” orders
+```sql
+SELECT
+ sm_order_key,
+ order_id,
+ order_gross_revenue,
+ order_refunds
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND ABS(order_refunds) > order_gross_revenue
+ORDER BY ABS(order_refunds) DESC
+LIMIT 200;
+```
+
+## Related resources
+
+- [Revenue Fields](/help-center/core-concepts/data-definitions/revenue-fields)
+- [`obt_orders` column docs](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
diff --git a/help-center/core-concepts/data-definitions/revenue-fields.mdx b/help-center/core-concepts/data-definitions/revenue-fields.mdx
new file mode 100644
index 0000000..257e3b8
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/revenue-fields.mdx
@@ -0,0 +1,64 @@
+---
+title: "Revenue Fields (Net vs Gross vs Total)"
+description: "How SourceMedium defines gross, net, and total revenue, and how discounts and refunds affect each."
+sidebarTitle: "Revenue Fields"
+icon: "currency-dollar"
+---
+
+SourceMedium exposes multiple revenue fields because “revenue” can mean different things depending on the question you’re answering.
+
+This page focuses on the **order-level** revenue fields you’ll see most often in:
+- `your_project.sm_transformed_v2.obt_orders`
+- `your_project.sm_transformed_v2.rpt_executive_summary_daily`
+- Many [SQL Query Library](/data-activation/template-resources/sql-query-library) recipes
+
+## Key fields (order-level)
+
+These are the canonical order-level fields in `obt_orders`:
+- `order_gross_revenue`: line-item revenue before discounts, excluding gift card purchases
+- `order_discounts`: discounts applied (see sign convention below)
+- `order_refunds`: refunds applied (see sign convention below)
+- `order_net_revenue`: gross revenue after discounts and refunds
+- `order_net_revenue_before_refunds`: gross revenue after discounts, before refunds
+- `order_total_revenue`: net revenue with shipping and taxes included (after discounts/refunds)
+
+## Important sign convention (discounts + refunds)
+
+In most SourceMedium tables, **discounts and refunds are stored as negative numbers** (or `0`).
+
+That means net revenue is additive:
+
+```sql
+-- Conceptual relationship
+order_net_revenue = order_gross_revenue + order_discounts + order_refunds
+```
+
+
+If you see positive refunds in your data, treat it as a data-quality edge case (some platforms can emit adjustments that violate the expected sign conventions).
+
+
+## Quick sanity-check query
+
+```sql
+SELECT
+ sm_store_id,
+ SUM(order_gross_revenue) AS gross_revenue,
+ SUM(order_discounts) AS discounts,
+ SUM(order_refunds) AS refunds,
+ SUM(order_net_revenue) AS net_revenue,
+ SUM(order_net_revenue_before_refunds) AS net_revenue_before_refunds,
+ SUM(order_total_revenue) AS total_revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
+GROUP BY 1
+ORDER BY net_revenue DESC
+LIMIT 50;
+```
+
+## Related resources
+
+- [Refund Logic](/help-center/core-concepts/data-definitions/refund-logic)
+- [`obt_orders` column docs](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+- [Metric Definitions](/onboarding/data-docs/metrics)
+
diff --git a/help-center/core-concepts/data-definitions/subscription-flags.mdx b/help-center/core-concepts/data-definitions/subscription-flags.mdx
new file mode 100644
index 0000000..59f50f0
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/subscription-flags.mdx
@@ -0,0 +1,44 @@
+---
+title: "Subscription Flags"
+description: "How SourceMedium classifies subscription orders and how to use first vs recurring subscription fields."
+sidebarTitle: "Subscription Flags"
+icon: "repeat"
+---
+
+Subscription reporting depends on consistent classification at the order (and sometimes line) level. SourceMedium provides several fields that work together:
+
+## Core fields
+
+Common subscription-related fields in `your_project.sm_transformed_v2.obt_orders` and `your_project.sm_transformed_v2.dim_orders`:
+- `sm_order_type`: order classification (subscription vs one-time)
+- `is_subscription_order`: boolean convenience field
+- `subscription_order_sequence`: first vs recurring subscription classification
+- `subscription_order_index`: sequential index of subscription orders per customer (when available)
+- `is_first_subscription_order`: convenience flag derived from `subscription_order_sequence`
+- `is_order_recurring_subscription`: convenience flag derived from `subscription_order_sequence`
+
+
+These fields are most reliable when you have a direct subscription-platform integration (or consistent subscription tagging in Shopify).
+
+
+## Recommended query pattern
+
+```sql
+SELECT
+ DATE_TRUNC(DATE(order_processed_at_local_datetime), MONTH) AS month_start,
+ subscription_order_sequence,
+ COUNT(*) AS order_count,
+ SUM(order_net_revenue) AS net_revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND is_subscription_order = TRUE
+ AND order_processed_at_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 365 DAY)
+GROUP BY 1, 2
+ORDER BY month_start DESC, subscription_order_sequence;
+```
+
+## Related resources
+
+- [Order Type (sm_order_type)](/data-transformations/order-segmentation/order-type)
+- [`obt_orders` column docs](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
diff --git a/help-center/core-concepts/data-definitions/utm-normalization.mdx b/help-center/core-concepts/data-definitions/utm-normalization.mdx
new file mode 100644
index 0000000..b44d2f7
--- /dev/null
+++ b/help-center/core-concepts/data-definitions/utm-normalization.mdx
@@ -0,0 +1,48 @@
+---
+title: "UTM Normalization"
+description: "How SourceMedium normalizes UTM fields and how to query UTM-based dimensions safely."
+sidebarTitle: "UTM Normalization"
+icon: "tag"
+---
+
+UTM fields are used across SourceMedium for segmentation, channel mapping, and conversion analysis. In many places, SourceMedium **already normalizes** these fields (lowercase, trimmed, and cleaned).
+
+
+If you’re joining or filtering on user-supplied strings (e.g., config sheet inputs, custom uploads), normalize on the fly:
+`LOWER(TRIM(value))`.
+
+
+## Canonical UTM fields
+
+You’ll commonly see:
+- `sm_utm_source`
+- `sm_utm_medium`
+- `sm_utm_campaign`
+- `sm_utm_content`
+- `sm_utm_term`
+- `sm_utm_source_medium` (combined convenience field)
+
+These fields appear in order tables and funnel tables, depending on data availability and attribution source.
+
+## Recommended query pattern (categorical-safe)
+
+```sql
+SELECT
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_source)), ''), '(unknown)') AS sm_utm_source,
+ COALESCE(NULLIF(LOWER(TRIM(sm_utm_medium)), ''), '(unknown)') AS sm_utm_medium,
+ COUNT(*) AS order_count,
+ SUM(order_net_revenue) AS net_revenue
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_processed_at_local_datetime >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
+GROUP BY 1, 2
+ORDER BY net_revenue DESC
+LIMIT 200;
+```
+
+## Related resources
+
+- [Attribution in SourceMedium](/help-center/core-concepts/attribution/attribution-in-sourcemedium)
+- [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+- [SQL Query Library](/data-activation/template-resources/sql-query-library)
+
diff --git a/help-center/core-concepts/data-health.mdx b/help-center/core-concepts/data-health.mdx
new file mode 100644
index 0000000..d83d3b2
--- /dev/null
+++ b/help-center/core-concepts/data-health.mdx
@@ -0,0 +1,148 @@
+---
+title: "Data Health"
+sidebarTitle: "Data Health"
+description: "Understand whether your data is fresh, available, and ready for analysis"
+icon: "stethoscope"
+---
+
+**Data Health answers one question: Is my data ready for analysis?**
+
+Before diving into revenue trends or cohort performance, you need to know whether the underlying data is complete and current. Data Health surfaces pipeline issues proactively so you can trust your answers, avoid surprises, and scope your analyses appropriately.
+
+## Why it matters
+
+Analytics are only as reliable as the data behind them.
+
+- **Stale data misleads**: A "last 7 days" analysis is useless if the most recent 3 days haven't synced
+- **Proactive visibility prevents bad decisions**: Catching a sync issue before a board meeting is better than discovering it afterward
+- **Scoping saves time**: Knowing which domains are ready helps you focus on answerable questions
+
+
+Data Health tells you whether the pipeline is working. [Attribution Health](/data-inputs/attribution-health/index) tells you whether your tracking is capturing marketing touchpoints. Both matter — a table can be perfectly fresh but still show 40% `(direct) / (none)` if UTM tracking isn't set up properly.
+
+
+---
+
+## What we check
+
+| Dimension | What it means |
+|-----------|---------------|
+| **Freshness** | Has the table been updated recently? We flag tables that haven't refreshed in 14+ days. |
+| **Availability** | Does the table contain data, or is it empty? |
+| **Domain Readiness** | Which analytical areas are usable — orders, customers, ads, attribution, etc.? |
+
+---
+
+## When data updates
+
+Most tables refresh on a **24-hour incremental schedule**. Our SLA guarantees **fresh data through yesterday** based on your reporting timezone. This means:
+
+- **Yesterday's data and earlier** is stable and complete
+- **Today's data** is not guaranteed and will be incomplete — avoid using it for analysis
+
+
+Real-time isn't the goal. We optimize for **accuracy over speed** — ensuring data is correctly transformed, deduplicated, and enriched before it reaches your dashboard or warehouse.
+
+
+### Platform-specific timing
+
+Some platforms have longer sync windows due to API limitations:
+
+| Platform | Typical Lag |
+|----------|-------------|
+| Shopify, Klaviyo, Meta, Google Ads | 24 hours |
+| Amazon Seller/Vendor Central, Amazon Ads | 24–72 hours (API rate limits) |
+| GA4 | 24–48 hours |
+
+---
+
+## Why 14 days?
+
+We use a **14-day threshold** to flag stale data because:
+
+- Most business analyses look at 7–30 day windows
+- A 14-day gap means you've lost visibility into recent trends
+- It's long enough to avoid false alarms from weekend or holiday pauses
+
+If a table hasn't refreshed in 14+ days, something is likely wrong with the sync.
+
+---
+
+## Common scenarios
+
+| What you see | What it likely means |
+|--------------|----------------------|
+| Orders table is stale | E-commerce platform sync may be delayed or disconnected |
+| Attribution table fresh but coverage low | Pipeline works, but tracking may not — check [Attribution Health](/data-inputs/attribution-health/index) |
+| Ad performance empty for a platform | That integration may not be connected |
+| Multiple tables 14+ days stale | Broader pipeline issue — recent analyses across domains are affected |
+| Single table stale, others fine | Platform-specific issue (API error, auth expiration, rate limits) |
+
+---
+
+## What to do if data is degraded
+
+
+
+ Identify which tables are stale. Is it one platform or multiple?
+
+
+ Avoid date ranges that depend on stale data. If orders haven't synced since Jan 15, don't analyze Jan 16–20.
+
+
+ If data is fresh but results look wrong (e.g., high `(direct) / (none)`), the issue may be tracking, not pipeline.
+
+
+ If staleness persists beyond 24–48 hours, reach out to your SourceMedium team — there may be an integration issue requiring admin attention.
+
+
+
+---
+
+## Example questions
+
+You can ask about data health in natural language:
+
+- "How is my data health?"
+- "Can I trust my last 7 days of data?"
+- "Which tables are fresh?"
+- "What data do I have available?"
+- "Are my tables up to date?"
+- "When was my orders data last updated?"
+
+
+Use the [AI Analyst](/ai-analyst/index) in Slack to run these checks. Just ask "How is my data health?" and get a real-time assessment of your table freshness and availability.
+
+
+---
+
+## Data Health vs Attribution Health
+
+| | Data Health | Attribution Health |
+|-|-------------|-------------------|
+| **Focus** | Table freshness and availability | Tracking and UTM coverage quality |
+| **Question it answers** | "Is my data pipeline working?" | "Is my marketing attribution accurate?" |
+| **When to check** | Before any analysis | When results look wrong despite fresh data |
+
+
+**Check Data Health first.** If data is stale, that explains why numbers look off. If data is fresh but attribution seems wrong, then check Attribution Health.
+
+
+---
+
+## Related resources
+
+
+
+ Diagnose and improve tracking coverage for marketing attribution.
+
+
+ Details on refresh schedules and platform-specific timing.
+
+
+ Common causes of missing attribution and how to fix them.
+
+
+ How SourceMedium structures and transforms your data.
+
+
diff --git a/help-center/core-concepts/data-transformation/data-architecture.mdx b/help-center/core-concepts/data-transformation/data-architecture.mdx
index f877cc3..7fddd77 100644
--- a/help-center/core-concepts/data-transformation/data-architecture.mdx
+++ b/help-center/core-concepts/data-transformation/data-architecture.mdx
@@ -25,5 +25,5 @@ We use data from your sales platform (Shopify, Amazon, etc) as the “source of
If you notice any mismatch between your Shopify Sales Report and your Executive Summary,
- see [this article](/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report) for possible explanations.
-
\ No newline at end of file
+ see [this article](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match) for possible explanations.
+
diff --git a/help-center/core-concepts/demographics/demographic-data-sources.mdx b/help-center/core-concepts/demographics/demographic-data-sources.mdx
new file mode 100644
index 0000000..79e2e98
--- /dev/null
+++ b/help-center/core-concepts/demographics/demographic-data-sources.mdx
@@ -0,0 +1,238 @@
+---
+title: "Demographic Data: What You Can (and Can’t) Do"
+description: "Where demographic attributes come from in SourceMedium, and how to use them for LTV analysis."
+sidebarTitle: "Demographic Data"
+icon: "users"
+---
+
+Brands often ask a version of:
+
+> “Meta Ads Manager can break down performance by age/gender/region. Can we ingest that into the warehouse—and use it for LTV?”
+
+This page explains what’s available in SourceMedium today, what typically isn’t, and the most practical paths to **LTV by demographic**.
+
+## The key constraint: LTV needs a customer-level identifier
+
+Ad platforms (including Meta) can report **campaign performance by demographic buckets** (e.g., impressions/conversions by age range), but those buckets generally **don’t include customer PII** and **can’t be joined to orders/customers** in your warehouse.
+
+That’s why platform demographic reporting is usually useful for:
+- **Creative and targeting diagnostics** (within the ad platform)
+- **Top-of-funnel performance by demographic**
+
+But not directly useful for:
+- **Customer LTV by demographic**
+
+## What SourceMedium already provides (by default)
+
+These are common “building blocks” you can use for demographic-style segmentation.
+
+### Geographic attributes
+
+- Customer address geography in `your_project.sm_transformed_v2.dim_customer_addresses` (e.g., `customer_address_city`, `customer_address_province`, `customer_address_country`) and a flag for the primary address (`is_default_address_for_customer`).
+- Order-level shipping geography in `your_project.sm_transformed_v2.obt_orders` (e.g., `order_shipping_city`, `order_shipping_state`, `order_shipping_country`).
+
+### Customer identity fields (PII)
+
+- `your_project.sm_transformed_v2.dim_customers` includes `customer_first_name`, `customer_last_name`, `customer_email`, `customer_phone_number`, and `customer_email_hashed`.
+
+
+PII and inferred demographic attributes can be sensitive. Make sure your collection, storage, and usage complies with your privacy policy and applicable laws.
+
+
+### Tags you can use for enrichment
+
+- Customer tags: `your_project.sm_transformed_v2.dim_customers.customer_tags_csv`
+- Order tags: `your_project.sm_transformed_v2.dim_orders.order_tags_csv`
+
+These are the most common way customers attach **self-reported** or **internally-derived** attributes (e.g., `gender:female`, `survey_age:25_34`, `persona:fitness`).
+
+## What SourceMedium typically does NOT provide by default
+
+- **Age** and **gender** (unless you collect/attach them yourself)
+- **Household** or **income** data
+- **Ad-platform demographic breakdown tables** (e.g., Meta “age/gender” breakdowns) in the standard transformed dataset
+
+If you want ad-platform demographic breakdowns as raw tables for analysis, contact SourceMedium support to scope feasibility and coverage.
+
+## Practical ways to get “LTV by demographic”
+
+### Option 1: Collect zero-party demographics (recommended when possible)
+
+Ask customers directly (pre-purchase quiz, account creation, post-purchase survey), then store the response in a way that lands in the warehouse (commonly via customer tags or order tags).
+
+
+Keep tag values normalized and stable (avoid free-text) so they’re usable in SQL, e.g., `gender:female`, `age_range:25_34`.
+
+
+### Option 2: First-party enrichment you already control
+
+Some brands collect attributes (gender, life stage, preferences) in their own systems and push them into e-commerce/CRM fields or tags. If your platform writes tags into your commerce system, those tags can flow into `customer_tags_csv` / `order_tags_csv`.
+
+### Option 3: Join third-party demographic enrichment
+
+If you purchase demographic enrichment from a third party, you can usually join it to SourceMedium customers using one of these join keys (depends on what your vendor provides):
+- `customer_email_hashed` (privacy-safe matching)
+- `customer_phone_number`
+- Address fields from `dim_customer_addresses` (street/zip/city)
+
+We recommend materializing a customer-level table keyed by `sm_customer_key` (for example, `dim_customer_demographics`) and keeping vendor fields in one place.
+
+### Option 4: Infer demographics (use cautiously)
+
+You can infer some attributes from PII (most commonly **gender from first name**). This can work as an 80/20 directional view at scale, but it will be imperfect and biased.
+
+
+Age inference is usually much less reliable than gender inference. If age is a must-have, prioritize collection (Option 1) or a vetted enrichment vendor (Option 3).
+
+
+### Option 5: Encode “audience segments” in campaign/creative naming (good for LTV by strategy)
+
+If the real question is “Which *targeting strategy* drives the best long-term customers?”, you can treat the “audience” as a **label** you control (not a true demographic attribute):
+
+1. Create dedicated campaigns / ad sets / creatives for each targeting strategy (keep overlap low).
+2. Put the segment label into a **joinable field that makes it to the warehouse**:
+ - Prefer UTMs on the landing page URL (e.g., `utm_campaign`, `utm_content`, `utm_term`).
+ - Campaign/ad set/ad names are useful only if you also pass that label through UTMs or another first-party capture method.
+3. Analyze LTV by that label using order/customer-level tables.
+
+In SourceMedium, last-click UTM fields like `sm_utm_campaign` / `sm_utm_content` / `sm_utm_term` are available on orders (see `your_project.sm_transformed_v2.obt_orders`), and event-level UTMs are available on funnel events (see `your_project.sm_transformed_v2.obt_funnel_event_history`).
+
+
+This yields **LTV by targeting strategy**, not “LTV by customer age/gender”. It’s often the most actionable answer for paid social, because the label is joinable to orders.
+
+
+#### Implementation checklist
+
+- Use a consistent UTM taxonomy across paid social (see [UTM Setup](/help-center/core-concepts/attribution/utm-setup)).
+- Keep the segment label coarse (e.g., `segment:female_25_34`, not an ad ID per creative).
+- QA by spot-checking recent orders in the warehouse and confirming the expected `sm_utm_*` values are populated (and not falling back to `(direct) / (none)`).
+
+## Example: Average customer LTV by primary country
+
+This example uses `dim_customer_addresses` for a customer's primary country and `obt_orders` for net revenue.
+
+
+Always filter `obt_orders` with `WHERE is_order_sm_valid = true` to exclude cancelled, test, and invalid orders from your analysis.
+
+
+```sql
+with customer_geo as (
+ select
+ sm_customer_key,
+ customer_address_country as country
+ from your_project.sm_transformed_v2.dim_customer_addresses
+ where is_default_address_for_customer = true
+),
+customer_ltv as (
+ select
+ sm_customer_key,
+ sum(order_net_revenue) as ltv
+ from your_project.sm_transformed_v2.obt_orders
+ where is_order_sm_valid = true
+ group by 1
+)
+select
+ coalesce(g.country, 'Unknown') as country,
+ count(*) as customers,
+ avg(l.ltv) as avg_ltv
+from customer_ltv l
+left join customer_geo g using (sm_customer_key)
+group by 1
+order by avg_ltv desc;
+```
+
+
+This query uses a `LEFT JOIN` so customers without a default address are grouped under "Unknown" rather than excluded. If you prefer to exclude them, use an `INNER JOIN` instead.
+
+
+## Example: Cohort LTV by "first purchase attribute" (discover what dimensions you have)
+
+If you use UTMs to encode audience strategy, a convenient way to view LTV over time is the cohort LTV report table:
+`your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`.
+
+
+This table contains **three rows per cohort**—one for each `sm_order_line_type` value (`all_orders`, `one_time_orders_only`, `subscription_orders_only`). Always filter to `sm_order_line_type = 'all_orders'` unless you specifically need subscription-only or one-time-only analysis.
+
+
+To see which cohort dimensions exist in your warehouse:
+
+```sql
+select
+ acquisition_order_filter_dimension,
+ count(*) as row_count
+from your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters
+where sm_order_line_type = 'all_orders'
+group by 1
+order by row_count desc;
+```
+
+To see example values for each dimension:
+
+```sql
+select
+ acquisition_order_filter_dimension,
+ count(distinct acquisition_order_filter_dimension_value) as distinct_values,
+ array_agg(distinct acquisition_order_filter_dimension_value limit 5) as example_values
+from your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters
+where sm_order_line_type = 'all_orders'
+group by 1
+order by distinct_values desc;
+```
+
+### Available dimensions
+
+| Dimension | Description | Example Values |
+|-----------|-------------|----------------|
+| `source/medium` | UTM source and medium | `google / organic`, `facebook / paid`, `bing / cpc` |
+| `campaign` | UTM campaign name | `fps-3-in-1-zp-amz`, `email #1 - bundle offer` |
+| `discount_code` | First-order discount code | `SAVE10`, `SAVE100` |
+| `sub_channel` | Marketing sub-channel | `Paid Social`, `Paid Search`, `Online DTC` |
+| `zero_party_attribution` | HDYHAU / post-purchase survey | `user_input: web search`, `user_input: my dermatologist recommended it` |
+| `order_type_(sub_vs._one_time)` | Subscription vs one-time | `Subscription`, `One-time`, `Subscription & One-time` |
+| `no_filters` | Unfiltered cohort totals | `No Filters` |
+
+### Example: 12-month LTV by acquisition source/medium
+
+
+Cohorts need 12+ months of history to have 12-month LTV values. Filter to cohorts at least 12 months old, or `ltv_12m` will be NULL.
+
+
+```sql
+select
+ acquisition_order_filter_dimension_value as source_medium,
+ cohort_month,
+ cohort_size,
+ max(case when months_since_first_order = 12
+ then cumulative_order_net_revenue / nullif(cohort_size, 0) end) as ltv_12m
+from your_project.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters
+where acquisition_order_filter_dimension = 'source/medium'
+ and sm_order_line_type = 'all_orders'
+ and cohort_month >= date_sub(current_date(), interval 24 month)
+ and cohort_month < date_sub(current_date(), interval 12 month)
+group by 1, 2, 3
+having ltv_12m is not null
+order by cohort_month desc, ltv_12m desc;
+```
+
+## Related resources
+
+
+
+ Central source of truth for customers, enrichment, and audiences
+
+
+ Make campaign and audience labels joinable to orders
+
+
+ How enrichment fits into SourceMedium’s transformation layer
+
+
+ Practical tagging patterns for segmentation and enrichment
+
+
+ Customer identity fields and join keys (including hashed email)
+
+
+ Customer geo attributes for segmentation
+
+
diff --git a/help-center/faq/account-management-faqs/account-management-faqs-home.mdx b/help-center/faq/account-management-faqs/account-management-faqs-home.mdx
index 8e26e7b..6a446a2 100644
--- a/help-center/faq/account-management-faqs/account-management-faqs-home.mdx
+++ b/help-center/faq/account-management-faqs/account-management-faqs-home.mdx
@@ -1,4 +1,23 @@
---
title: "Account Management FAQs"
+description: "Frequently asked questions about managing your SourceMedium account, team access, integrations, and security"
sidebarTitle: "Overview"
----
\ No newline at end of file
+icon: "question-mark"
+---
+
+Use this section for common account operations: getting teammates access, understanding permissions, connecting tools, and security basics.
+
+## Access & permissions
+
+- [How do I invite users or groups to my dashboard?](/onboarding/analytics-tools/looker-studio-guide)
+- [How do I give dashboard access to a teammate?](/help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate)
+- [How do I set up a Google group?](/onboarding/analytics-tools/google-groups-access-control)
+
+## Setup & security
+
+- [What data security practices are in place at SourceMedium?](/help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium)
+- [What to know about connecting Google Analytics to SourceMedium](/help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium)
+
+## Working with the team
+
+- [What is the process for requesting and scoping custom work?](/help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work)
diff --git a/help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data.mdx b/help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data.mdx
index 1e114c1..a4916b8 100644
--- a/help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data.mdx
+++ b/help-center/faq/account-management-faqs/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data.mdx
@@ -1,5 +1,6 @@
---
title: "Are you utilizing customer and order tagging for deeper enrichment of your data?"
+description: "How to use Shopify customer and order tags to enrich your SourceMedium data with demographics, purchase patterns, and marketing insights"
sidebarTitle: "Customer & Order Tagging"
icon: 'question-mark'
---
@@ -31,4 +32,4 @@ Overall, utilizing customer and order tagging is an essential component of any d
- [Skio](https://integrate.skio.com/skio/extras/subscription-tags)
- [Stay AI](https://stay.ai/features-subscription-basics/)
- [SPINS](https://www.spins.com/tag/shelf-tags/)
-
\ No newline at end of file
+
diff --git a/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey.mdx b/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey.mdx
index e9706f9..decb055 100644
--- a/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey.mdx
+++ b/help-center/faq/account-management-faqs/best-practices-in-setting-up-a-post-purchase-hdyhau-survey.mdx
@@ -1,63 +1,312 @@
---
-title: "Best practices in setting up a post-purchase HDYHAU survey"
-sidebarTitle: "Post-purchase HDYHAU best practices"
-icon: 'question-mark'
+title: "Best Practices for Post-Purchase HDYHAU Surveys"
+sidebarTitle: "Post-Purchase Survey Setup"
+description: "How to set up effective 'How Did You Hear About Us?' surveys to collect zero-party attribution data"
+icon: 'square-poll-vertical'
---
-### Best practices in setting up a “How Did You Hear About Us?” survey to collect zero-party data
-### Survey Setup
+## What is a HDYHAU Survey?
-The main copy used and the options selected should be specific for your brand and respective marketing channels. Different platforms offer different ways to set up questions, but these are the general options we recommend.
+A "How Did You Hear About Us?" (HDYHAU) survey collects **zero-party data**—information customers voluntarily provide about how they discovered your brand. This data is valuable because:
-**Title**: How did you first hear about us?
+- **Privacy-resistant**: Not affected by cookie blockers, iOS privacy features, or ad blockers
+- **Top-of-funnel visibility**: Captures awareness channels that tracking can't see (word of mouth, podcasts, TV)
+- **Validates tracking data**: Cross-reference with your analytics to identify attribution gaps
-**Introduction text**: [leave blank]
+
+Zero-party data complements (not replaces) your tracking-based attribution. Use both for a complete picture of your marketing performance.
+
-**Placeholder text**: choose an option
+See: [Zero-Party Attribution](/help-center/core-concepts/attribution/zero-party-attribution)
-**Button text**: submit
+---
+
+## Survey Placement & Timing
+
+
+
+ Display the survey immediately after purchase on the order confirmation/thank-you page.
+
+ **Pros:**
+ - Highest response rates (15-30%)
+ - Customer is already engaged
+ - Memory is fresh
+
+ **Cons:**
+ - Can slow checkout flow slightly
+
+
+ Send survey via email after order confirmation.
+
+ **Pros:**
+ - Doesn't interrupt checkout
+ - Can include follow-up questions
+
+ **Cons:**
+ - Lower response rates (3-8%)
+ - Delay may affect memory accuracy
+
+
+
+
+For optimal response rates, display the survey on the thank-you page. Most survey tools (Fairing, KnoCommerce, Zigpoll) support this placement out of the box.
+
+
+---
+
+## Survey Setup
+
+### Question Copy
+
+| Element | Recommendation |
+|---------|----------------|
+| **Question** | "How did you first hear about us?" |
+| **Introduction text** | Leave blank (keep it short) |
+| **Placeholder text** | "Choose an option" |
+| **Button text** | "Submit" |
+
+
+The word **"first"** is important—it prompts customers to think about initial discovery, not their most recent interaction.
+
+
+### Standard Response Options
+
+Include channels where you actively market. Order matters for accurate data:
-
-- Facebook
+
+- Facebook / Meta
- Instagram
- TikTok
-- Google (or other search engine)
-- Youtube
+- Google Search
+- YouTube
- Podcast
-- Blog or press
-- Influencer
-- Friend - family - coworker
+- Blog / Press / Article
+- Influencer / Creator
+- Email / Newsletter
+- Friend / Family / Coworker
+- I don't remember
- Other
-
+
+Add these if you have meaningful spend or presence:
+
- Pinterest
- Snapchat
+- Streaming TV / CTV
+- Linear TV
+- Radio
+- Billboard / Out of Home
+- Direct Mail
+- Reddit
+- Twitter / X
+- LinkedIn (B2B)
- Bing Search
-- Google (or other search engine)
- - Can be broken into two or more questions depending on the platforms you're looking to track.
-### Recommended Survey/Question Settings
+
+**Always include "I don't remember"** as an option. Without it, customers who genuinely don't recall will select a random channel, polluting your data. Research shows 10-20% of respondents legitimately don't remember.
+
+
+---
+
+## Survey Settings & Best Practices
+
+### Response Order
+
+
+
+ Randomize the display order of channels to prevent position bias (first options get selected more often).
+
+
+ Keep "I don't remember" and "Other" pinned at the bottom—these should always be last.
+
+
+
+### Control Option (Validation Check)
+
+Add a "control" channel you **don't** use to detect random clicking:
-- Display the options in random order, if possible.
-- Add a “fake” response option for a marketing channel that you aren't currently using (e.g. TV)
-- Optional: Select Only **capture one response per customer.**
-- Optional: Enable free form “Other” option if you would like richer qualitative response data
+```
+Example: If you don't advertise on TV, include "TV Commercial" as an option.
+```
-### Customer and Order Tagging
+If this control option receives significant responses (>5%), it indicates:
+- Customers are clicking randomly
+- Your question may be confusing
+- Response data quality may be compromised
-- Enable customer and order level tagging (note, for some platforms this is an upsell feature for a more premium plan)
-- Label with the prefix **HDYHAU-** or **PPS-**
- - This label will be easier to identify for filtering in the SourceMedium dashboard and will show as something like **HDYHAU-Facebook**
+
+A well-designed survey should see <3% responses for the control option.
+
+
+### Response Settings
+
+| Setting | Recommendation |
+|---------|----------------|
+| **Responses per customer** | One response only (prevents duplicate data) |
+| **Free-form "Other"** | Enable—captures channels you haven't listed |
+| **Required vs Optional** | Optional (required surveys reduce completion rates) |
+
+---
+
+## Improving Response Rates
+
+
+
+ One question is ideal. Each additional question reduces completion by ~20%.
+
+
+ Ensure options are tap-friendly on mobile (most Shopify traffic is mobile).
+
+
+ Match your brand's look and feel. A cohesive design feels less intrusive.
+
+
+ Some brands offer discount codes for survey completion (use sparingly—can bias responses).
+
+
+
+---
-### Where can zero party data be used in the SourceMedium dashboard?
+## Customer & Order Tagging
-- New Customers - customer tag required
-- Last Order Analysis - customer tag required
-- Orders Deep Dive - order tag required
-- Post Purchase Survey Module [BETA] - ask the SourceMedium team for early access!
+Enable tagging so responses flow into SourceMedium and your other analytics tools.
+
+### Tag Format
+
+Use a consistent prefix for easy filtering:
+
+| Prefix | Example Tag |
+|--------|-------------|
+| `HDYHAU-` | `HDYHAU-Facebook` |
+| `PPS-` | `PPS-TikTok` |
+| `survey-` | `survey-Podcast` |
+
+
+Most survey platforms (Fairing, KnoCommerce, Zigpoll) support both **customer tags** and **order tags**. Enable both for maximum flexibility in reporting.
+
+
+### Platform-Specific Setup
+
+
+
+ Enterprise-grade surveys with advanced targeting and A/B testing.
+
+
+ Zero-party data platform with multi-question flows.
+
+
+ Lightweight surveys with Shopify-native integration.
+
+
+
+---
+
+## Using Survey Data in SourceMedium
+
+Once tagging is configured, HDYHAU data appears in these modules:
+
+| Module | Tag Type Required |
+|--------|-------------------|
+| **New Customers Analysis** | Customer tag |
+| **Last Order Analysis** | Customer tag |
+| **Orders Deep Dive** | Order tag |
+| **Post-Purchase Survey Module** | Order tag |
+
+
+The Post-Purchase Survey Module provides dedicated reporting for zero-party data. Contact the SourceMedium team for access.
+
+
+---
+
+## Backfilling Historical Orders
+
+If you have survey responses from before your tagging was configured (spreadsheets, old survey tools, manual records), you can backfill tags to historical orders.
+
+
+
+ Best for tagging a few dozen orders manually.
+
+ 1. Go to **Orders** in Shopify Admin
+ 2. Filter or search for the orders you need to tag
+ 3. Select the orders (checkbox)
+ 4. Click **More actions** → **Add tags**
+ 5. Enter tag (e.g., `HDYHAU-Facebook`)
+
+
+ You can select up to 50 orders at a time in the Shopify admin.
+
+
+
+ Best for tagging hundreds or thousands of orders from a spreadsheet.
+
+ 1. Export your orders from Matrixify (or start with your survey response spreadsheet)
+ 2. Add/update the `Tags` column with your HDYHAU tags
+ 3. Import back via Matrixify
+
+ ```
+ Order Name,Tags
+ #1001,HDYHAU-Facebook
+ #1002,HDYHAU-TikTok
+ #1003,HDYHAU-Podcast
+ ```
+
+
+ Matrixify merges tags by default—your new tags will be added to existing tags, not replace them.
+
+
+
+ Best for rule-based tagging (e.g., tag all orders from a date range).
+
+ Create a Flow that:
+ 1. Triggers on order criteria (date, product, customer segment)
+ 2. Adds the appropriate HDYHAU tag
+
+
+ Shopify Flow requires Shopify Plus or the Flow app on Advanced plans.
+
+
+
+
+
+**Tag format matters.** Use the same prefix format (`HDYHAU-`, `PPS-`, etc.) as your survey tool to ensure SourceMedium can recognize and report on all your zero-party data consistently.
+
+
+---
+
+## Common Pitfalls to Avoid
+
+
+
+ Forces customers to guess, corrupting your data. Always include this option.
+
+
+ More than 12-15 options overwhelms customers. Group similar channels (e.g., "Social Media" instead of listing every platform).
+
+
+ First options receive disproportionate clicks. Randomize to get accurate distribution.
+
+
+ "How did you hear about us?" captures discovery. For last touchpoint, use "What brought you back today?"—but this is usually better captured via tracking.
+
+
+
+---
-### Additional information and related articles
+## Related Resources
-- [Tagging orders with Fairing (Enquire)](https://help.sourcemedium.com/articles/how-do-i-tag-orders-with-post-purchase-survey-results-from-enquire)
\ No newline at end of file
+
+
+ Strategies for improving your overall attribution coverage.
+
+
+ Connect Fairing survey responses to SourceMedium.
+
+
+ Set up KnoCommerce for zero-party data collection.
+
+
+ How survey responses map to your channel groupings.
+
+
diff --git a/help-center/faq/account-management-faqs/bigquerey-csv-upload-guide.mdx b/help-center/faq/account-management-faqs/bigquery-csv-upload-guide.mdx
similarity index 89%
rename from help-center/faq/account-management-faqs/bigquerey-csv-upload-guide.mdx
rename to help-center/faq/account-management-faqs/bigquery-csv-upload-guide.mdx
index 6ac52ae..bc4e17f 100644
--- a/help-center/faq/account-management-faqs/bigquerey-csv-upload-guide.mdx
+++ b/help-center/faq/account-management-faqs/bigquery-csv-upload-guide.mdx
@@ -1,5 +1,6 @@
---
title: "How do I upload a CSV file to my BigQuery instance?"
+description: "Step-by-step instructions for uploading CSV files to your BigQuery data warehouse from your local machine"
sidebarTitle: "BigQuery CSV Upload Guide"
icon: 'question-mark'
---
@@ -23,4 +24,4 @@ icon: 'question-mark'
7. Once you've done the above, click the “CREATE TABLE” button
8. You can now search for your table and query it's contents from your data explorer
- 
\ No newline at end of file
+ 
diff --git a/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution.mdx b/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution.mdx
index 76d795a..cb49e42 100644
--- a/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution.mdx
+++ b/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution.mdx
@@ -1,5 +1,6 @@
---
title: "How can I improve my last-click UTM attribution?"
+description: "Best practices for UTM naming conventions, tracking setup, and common pitfalls to improve your marketing attribution coverage"
icon: 'question-mark'
---
### Requirements
@@ -12,16 +13,35 @@ A UTM, also known as the Urchin Tracking Module, is a string that can be attache
Having a clear set of conventions for UTMs from the start will pay dividends down the line for ease of tracking where your most valuable customers are converting from!
+See: [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+
### **Steps**
1. Check to see that UTMs are applied to all relevant marketing campaigns where links are distributed, from Meta, Google, TikTok, to Influencers & Affiliates
-2. Streamline proper naming conventions for UTMs using our best practices [[click HERE for our shareable template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0)]
+2. Streamline proper naming conventions for UTMs using our best practices ([click HERE for our shareable template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0))
3. Watch out for direct/none UTM tracking, which is a sign that your data and website setup may need fine tuning [ask the team about our **data and analytics audit** where we help to diagnose common pitfalls with tracking]
### **Additional Information**
- Historical UTMs cannot be changed or applied retroactively - employing best practices early is critical!
- Changing UTMs of successful marketing campaigns on major channels such as Meta and Google can have a material impact on performance — reach out to the SourceMedium team to learn more about the risks with changing your UTMs
-- Pairing zero party data with lack-click UTM attribution can be a powerful combination — ask our team about our advanced `Zero Party Data Module`
+- Pairing zero party data with last-click UTM attribution can be a powerful combination — ask our team about our advanced `Zero Party Data Module`
+
+---
----
\ No newline at end of file
+### Related Articles
+
+
+
+ What UTMs are, what each value means, and how to tag links.
+
+
+ Diagnose and reduce missing attribution.
+
+
+ Use surveys to capture discovery channels tracking can’t see.
+
+
+ A toolkit for improving overall attribution coverage.
+
+
diff --git a/help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate.mdx b/help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate.mdx
index 221b543..c76b391 100644
--- a/help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate.mdx
+++ b/help-center/faq/account-management-faqs/how-do-i-give-dashboard-access-to-a-teammate.mdx
@@ -1,5 +1,6 @@
---
-title: "How do I give dashboard access to a teammate??"
+title: "How do I give dashboard access to a teammate?"
+description: "How to invite team members to view your SourceMedium dashboards using Google Access Groups and manage permissions"
sidebarTitle: "Giving Dashboard Access"
icon: 'question-mark'
---
@@ -19,4 +20,4 @@ Your team can provision dashboard access at any plan-level.

----
\ No newline at end of file
+---
diff --git a/help-center/faq/account-management-faqs/how-do-i-invite-users-to-my-dashboard.mdx b/help-center/faq/account-management-faqs/how-do-i-invite-users-to-my-dashboard.mdx
deleted file mode 100644
index 1a38eca..0000000
--- a/help-center/faq/account-management-faqs/how-do-i-invite-users-to-my-dashboard.mdx
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: "How do I invite users or groups to my dashboard? What are Looker Studio permissions and why do they matter?"
-sidebarTitle: "Inviting users/groups to you dashboard"
-icon: 'question-mark'
----
-### How to add users or groups to a Looker Studio dashboard:
-
-1. Access the Share menu by clicking the button in the top right-hand corner of the dashboard.
-
- 
-
-2. Add the user or group email to the Email text box. ***(Note: Any number of emails can be added at once)***
-
-
-3. Once all emails have been added choose the level of permission you wish this group of emails to have.
-**(See Permissions section below for a discussion of permissions and related best practices)**
-
- 
-
-4. Optionally emails can be notified when they've been added to the dashboard before pressing the Send button to finish adding dashboard users.
-
-### Dashboard Permissions
-
-Looker Studio offers two straightforward permissions options:
-
-**Viewer:**
- - Can view the report and interact with controls
- - Can view the data source schema
-
-**Editor**
- - Can modify the report
- - Can share the report
-
-We recommend providing all but the users that will maintain the dashboard with Viewer permissions. This is to prevent unintentional edits that could disrupt the use of a dashboard.
-
-[For a more detailed look at permissions, Google offers excellent documentation here](https://support.google.com/looker-studio/answer/10403868?visit_id=638370456149651997-1053185419&p=cm-roles&rd=1).
\ No newline at end of file
diff --git a/help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group.mdx b/help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group.mdx
deleted file mode 100644
index a742164..0000000
--- a/help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group.mdx
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: "How do I set up a Google Group?"
-icon: 'question-mark'
----
-
-# Creating Access Groups
-
-There are many reasons for creating Access Groups within Google.
-
-- **Increased security:** Access groups can help to improve security by allowing you to control who has access to specific services and resources.
-- **Simplified administration:** Access groups can help to simplify administration by making it easier to manage user permissions. For example, if you have a large organization with many users, you could create a separate access group for each department or team. This would make it easy to assign the appropriate permissions to each group of users.
-- **Improved collaboration:** Access groups can help to improve collaboration by making it easier for users to share files and collaborate on projects.
-
-Here is how you set up an Access Group within Google:
-
-1. Ensure you are logged into the correct email for the organization you are creating the group for.
-2. Launch [groups.Google.com](http://groups.google.com/) in your browser.
-3. Click Create Group.
-
- 
-
-4. The next window is going to allow you to name the group, give it an email and also a description. Once you do so, click Next.
-
- 
-
-5. Next, you'll be able to set the Privacy Settings for the Group.
- - Choose who can search for the group and who can join *(only invited users or anyone for example).*
-
- 
-
-6. Once you have named the group and set the privacy settings, you can add group members by adding emails in the Group Members box. Once you have added the emails of those you want to join the group, hit Create group.
-
-
-
-Your access group has been created! **You can now share the group's email with your dashboard**.
-
-You can always go back to your group and add additional members and change permissions.
-
-Add additional members by hitting the blue Add Members button at the top.
-
-
-
-If you want to make adjustments to permissions, you will want to go to Group Settings and from there, you can make permission adjustments as needed.
-
-
-
-Different levels of permission:
-
-- Owner = Full control over assets
-- Manager = Can modify and share assets
-- Member = Can view assets
-
-One final piece to note, if you are wanting to add members outside of your organization, make sure to update the Group Settings to allow for members outside of the organization to be allowed access.
-
-
-
-*For additional information, check out [Google's Looker documentation for Groups](https://cloud.google.com/looker/docs/admin-panel-users-groups).*
\ No newline at end of file
diff --git a/help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce.mdx b/help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce.mdx
index c2f4934..1e62072 100644
--- a/help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce.mdx
+++ b/help-center/faq/account-management-faqs/how-do-i-setup-post-purchase-survery-order-tagging-for-knocommerce.mdx
@@ -1,5 +1,6 @@
---
title: "How do I setup Post-Purchase Survey order tagging for KnoCommerce?"
+description: "Configure KnoCommerce to automatically tag Shopify orders with HDYHAU survey responses for zero-party attribution"
sidebarTitle: "Tagging Orders with KnoCommerce PPS results"
icon: 'question-mark'
---
@@ -29,4 +30,4 @@ This will start tagging orders with responses to the Post Purchase Survey questi
### **Additional information and related articles**
-- [Video from Kno on how to set up tagging](https://www.loom.com/share/a8815bf809f5499090afb2dfdaff1d36)
\ No newline at end of file
+- [Video from Kno on how to set up tagging](https://www.loom.com/share/a8815bf809f5499090afb2dfdaff1d36)
diff --git a/help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire.mdx b/help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire.mdx
index 247a1be..fc3e339 100644
--- a/help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire.mdx
+++ b/help-center/faq/account-management-faqs/how-do-i-tag-orders-with-post-purchase-survey-results-from-fairing-enquire.mdx
@@ -1,5 +1,6 @@
---
title: "How do I tag orders with post-purchase survey results from Fairing (Enquire)?"
+description: "Set up Shopify Flow to automatically tag orders with Fairing post-purchase survey responses for attribution analysis"
sidebarTitle: "Tagging Orders with Fairing PPS results"
icon: 'question-mark'
---
diff --git a/help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel.mdx b/help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel.mdx
index 5b62d93..1fa9fb4 100644
--- a/help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel.mdx
+++ b/help-center/faq/account-management-faqs/moving-slack-bot-to-another-channel.mdx
@@ -1,5 +1,6 @@
---
title: "How to move your Slack report bot to another Slack channel"
+description: "Step-by-step guide to reinstalling the SourceMedium Slack Bot to a different channel in your workspace"
icon: 'question-mark'
---
diff --git a/help-center/faq/account-management-faqs/test-image-doc.mdx b/help-center/faq/account-management-faqs/test-image-doc.mdx
deleted file mode 100644
index 8109eb3..0000000
--- a/help-center/faq/account-management-faqs/test-image-doc.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Test Images"
-icon: 'question-mark'
----
\ No newline at end of file
diff --git a/help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium.mdx b/help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium.mdx
index fcd384c..956f1c2 100644
--- a/help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium.mdx
+++ b/help-center/faq/account-management-faqs/what-data-security-practices-are-in-place-at-sourcemedium.mdx
@@ -1,5 +1,6 @@
---
title: "What data security practices are in place at SourceMedium?"
+description: "How SourceMedium protects your data with encryption, access controls, PII handling, and security incident response procedures"
sidebarTitle: "Security Practices at SourceMedium"
icon: 'question-mark'
---
@@ -19,4 +20,4 @@ icon: 'question-mark'
• We provide written notice without undue delay (but in no event longer than twenty-four (24) hours) to customer if we reasonably suspect that a security incident has taken place. Such notice will include all available details required under Data Protection Laws for customer to comply with its own notification obligations to regulatory authorities or individuals affected by the security incident
----
\ No newline at end of file
+---
diff --git a/help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium.mdx b/help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium.mdx
index 39c09b7..b436639 100644
--- a/help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium.mdx
+++ b/help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium.mdx
@@ -1,5 +1,6 @@
---
title: "What impact does Global-E have in SourceMedium?"
+description: "How Global-E international shipping affects revenue and tax calculations in your SourceMedium dashboard"
sidebarTitle: "Global-E's impact in SourceMedium"
icon: 'question-mark'
---
diff --git a/help-center/faq/account-management-faqs/what-is-last-click-attribuion.mdx b/help-center/faq/account-management-faqs/what-is-last-click-attribution.mdx
similarity index 66%
rename from help-center/faq/account-management-faqs/what-is-last-click-attribuion.mdx
rename to help-center/faq/account-management-faqs/what-is-last-click-attribution.mdx
index c1d9187..61212bc 100644
--- a/help-center/faq/account-management-faqs/what-is-last-click-attribuion.mdx
+++ b/help-center/faq/account-management-faqs/what-is-last-click-attribution.mdx
@@ -1,11 +1,14 @@
---
title: "What is Last Click Attribution?"
+description: "Understanding last click attribution in SourceMedium and how UTM tracking determines which marketing channel gets credit for a conversion"
icon: 'question-mark'
---
Attribution is a method used in digital marketing to identity how much each marketing channel has contributed to your sales efforts. Where did your customer come from and what caused them to make a purchase? Last Click Attribution is a model of assigning credit to a conversion based on the last touchpoint a customer has with a website before making a purchase.
In SourceMedium, last click attribution is based on your UTM configuration set up. Properly set up UTMs will allow you to see where your customers are coming from right before they make their purchase.
+See: [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+
### For Example:
If a customer clicks on a Facebook ad and then a few days later visits the site through a Google Search right before then making a purchase, the attribution to the purchase will go to Google (the last click).
@@ -39,12 +42,25 @@ In addition, we stitch GA data with Shopify data to get the best UTM coverage an
Last click attribution has the least likelihood of breaking compared to the other stages of tracking. When combined with information like a post purchase survey, last click attribution can help you understand a customer's journey of where they found your company and what marketing channels they were influenced by.
-### Related Articles:
-
-[How can I improve my last-click UTM attribution?](https://help.sourcemedium.com/articles/how-can-i-improve-my-last-click-utm-attribution)
-
-[Do you have a proper Google Analytics setup?](https://help.sourcemedium.com/articles/do-you-have-a-proper-google-analytics-setup)
-
-[Are you utilizing customer and order tagging for deeper enrichment of your data?](https://help.sourcemedium.com/articles/are-you-utilizing-customer-and-order-tagging-for-deeper-enrichment-of-your-data)
-
-[What attribution windows does SourceMedium report on for marketing platforms?](https://help.sourcemedium.com/articles/what-attribution-windows-does-source-medium-report-on-for-marketing-platforms)
\ No newline at end of file
+### Related Articles
+
+
+
+ What UTMs are, what each value means, and how to tag links.
+
+
+ Best practices for UTM tracking hygiene.
+
+
+ Common causes and fixes for missing attribution.
+
+
+ Enrich your data with zero-party attribution.
+
+
+ How SourceMedium reports platform attribution windows.
+
+
+ Strategies for improving attribution coverage.
+
+
diff --git a/help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work.mdx b/help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work.mdx
index e83c35d..52b7c7b 100644
--- a/help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work.mdx
+++ b/help-center/faq/account-management-faqs/what-is-the-process-for-requesting-and-scoping-custom-work.mdx
@@ -1,11 +1,12 @@
---
title: "What is the process for requesting & scoping custom work?"
+description: "How to request custom dashboard work, understand customization allowances, and scope analyst-on-demand projects with SourceMedium"
sidebarTitle: "Requesting & Scoping Custom Work"
icon: 'question-mark'
---
### Requirements
-Customers must be on a **non-trial/paid Pro or Enterprise plan**
+Customers must be on a **paid Pro or Enterprise plan**
### Background
@@ -45,7 +46,7 @@ We support one round of customizations to your Executive Summary report during t
- Changing defaults (date range, day/week/month aggregation, metrics visualized)
- Exposing additional metrics/filters to existing designed visualizations and report pages that are not exposed by default, as long as these metrics or dimensions are included in the SourceMedium data layer
- Enabling deeper data layer functionalities like influencer tracking, target setting, scorecards, multi-store or multi-channel visualization modules, and other outputs found within our template gallery
- - Visualizations from our [**Template Gallery**](https://help.sourcemedium.com/articles/template-gallery)
+ - Visualizations from our [**Template gallery**](/help-center/template-gallery)
#### Advanced Customizations
- More customized visualizations outside of the template gallery or existing dashboards
- Bring in external data from custom Google sheets into dashboard (if complex, bespoke)
@@ -56,4 +57,4 @@ We support one round of customizations to your Executive Summary report during t
### **Additional information and related articles**
-- [Where can I find examples of SourceMedium visualizations?](https://www.notion.so/Where-can-I-find-samples-of-Source-Medium-Visualizations-3c4ca397aa924611994487ba8fc591cd?pvs=21)
\ No newline at end of file
+- [Where can I find examples of SourceMedium visualizations?](/help-center/template-gallery)
diff --git a/help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report.mdx b/help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report.mdx
index 2a19f38..c9f8ab6 100644
--- a/help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report.mdx
+++ b/help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report.mdx
@@ -1,5 +1,6 @@
---
title: "What metrics can I include in my daily Slack Bot report?"
+description: "Available metrics for your SourceMedium Slack Bot daily report including revenue, orders, marketing spend, and subscription metrics"
icon: 'question-mark'
---
## Follow this guide for configuring your daily Slack Bot report
@@ -8,7 +9,7 @@ icon: 'question-mark'
• Paid **Pro** or **Enterprise** Plan on SourceMedium
-• [**Slack bot properly installed for your Shopify store(s)**](https://help.sourcemedium.com/articles/source-medium-report-analytics-slack-bot-setup)
+• [**Slack bot properly installed for your Shopify store(s)**](/help-center/slack-bot-setup)
• Directly connected subscription platform to SourceMedium (if a subscription based store)
@@ -44,4 +45,4 @@ icon: 'question-mark'
-2. For non-defaulted metrics, this daily slack report can be customized with up to 10 of the metrics that can be found on the 'Executive Summary' dashboard ([see here](https://airtable.com/shrVwL4GTM4WJ93h8/tblkfb5z544UzFuZT)). Just reach out to a CSA and let them know what you'd like to see!
\ No newline at end of file
+2. For non-defaulted metrics, this daily slack report can be customized with up to 10 of the metrics that can be found on the 'Executive Summary' dashboard ([see here](https://airtable.com/shrVwL4GTM4WJ93h8/tblkfb5z544UzFuZT)). Just reach out to a CSA and let them know what you'd like to see!
diff --git a/help-center/faq/account-management-faqs/what-to-know-about connecting-google-analytics-to-sourcemedium.mdx b/help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium.mdx
similarity index 57%
rename from help-center/faq/account-management-faqs/what-to-know-about connecting-google-analytics-to-sourcemedium.mdx
rename to help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium.mdx
index e7151c3..243cc2b 100644
--- a/help-center/faq/account-management-faqs/what-to-know-about connecting-google-analytics-to-sourcemedium.mdx
+++ b/help-center/faq/account-management-faqs/what-to-know-about-connecting-google-analytics-to-sourcemedium.mdx
@@ -1,16 +1,29 @@
---
title: "What to know about connecting Google Analytics to SourceMedium"
+description: "How SourceMedium integrates Google Analytics data with Shopify using the Attribution Source Hierarchy, and common reasons for data discrepancies"
sidebarTitle: "Connecting Google Analytics to SourceMedium"
icon: 'question-mark'
---
Google Analytics is a powerful system for understanding user behavior. When you connect SourceMedium to Google Analytics, SourceMedium will stream and integrate your 'GA' data into your dashboard and other data sources. The integration of this data can be fairly involved, so let's break it down to just the main things that give the maximum amount of clarity.
-### How Google Analytics data is Integrated - the “Attribution Waterfall”
+### How Google Analytics data is Integrated - the “Attribution Source Hierarchy”
-When integrating data, it's important to decide on a most trustworthy data source to use as a foundation. At SourceMedium we use Shopify data as our Source of Truth, as Shopify data is robust and represents real financial transactions. When we integrate Google Analytics data with Shopify data, we trust Shopify more than Google Analytics - this hierarchy of trust is called our “Attribution Waterfall.” In short, when we report this integrated data, we are showing Shopify data which has been enriched and expanded by Google Analytics.
+When integrating data, we focus on **Best-Signal Selection**. SourceMedium uses Shopify as the robust transactional foundation (Source of Truth for "what was sold"), but we actively **enhance** that record with attribution signals from Google Analytics and other platforms.
+
+Rather than just "trusting" one over the other, we intelligently merge them. We prioritize the most specific and reliable signal for each order—this is our [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy). In short, we report an aggregated dataset where Shopify's financial records are enriched by GA's behavioral data.
+
+For the full priority order, see [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy).
This enrichment can fill in gaps in both data sources — SourceMedium can regularly provide attribution for 10-30% more orders than Google Analytics on its own.
+### Technical matching note
+
+For GA transaction-to-order matching, Shopify-style transaction IDs like `#1234` are now tie-eligible alongside longer numeric-suffix IDs.
+
+Matching is still bounded by attribution windows and overall data quality, so discrepancies can remain when upstream tracking is missing, delayed, or inconsistent.
+
+For full matching and source-priority mechanics, see [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy).
+
### Why doesn't Shopify/SourceMedium match Google Analytics?
Google Analytics has some common failure points that can cause data sources to diverge:
@@ -21,17 +34,27 @@ Google Analytics has some common failure points that can cause data sources to d
- Adblockers
- The data that GA provides is generally only as good as the tracking, and most, if not all tracking tech (pixels, cookies, tag, etc.) can be circumvented by customers.
+ The data that GA provides is generally only as good as the tracking, and most, if not all tracking tech (pixels, cookies, tags, etc.) can be circumvented by customers.
- Faulty Tracking
- There's no absolute right or wrong approach for setting up UTMs, but most companies make some sort of mistake when setting up tracking. The best practices we have identified are covered in this [starter doc](https://www.notion.so/How-can-I-improve-my-last-click-UTM-attribution-0a6796ff8de54b1498aeb7643cbfa0bd?pvs=21) and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
+ There's no absolute right or wrong approach for setting up UTMs, but most companies make some sort of mistake when setting up tracking. Start with [UTM Setup](/help-center/core-concepts/attribution/utm-setup), then follow [Improving Last-Click Attribution](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution) and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).
- Factors not visible to SourceMedium
Tracking is complex, and many other factors that are not visible to SourceMedium can come into play. It is generally reasonable to expect 10-20% discrepancies between Shopify (source of truth) and GA.
+### Intelligent Data Aggregation
+
+SourceMedium doesn't just rely on one method. Instead, we **aggregate first-party data captured from all sources** and intelligently merge it to create the highest quality record.
+
+This means:
+- **More Data Sources = Better Output**: Connecting more platforms gives SourceMedium more signals to resolve identity and attribution.
+- **Better Capture = Better Output**: Improvements to your upstream tracking (e.g., a robust GA4 setup or server-side tracking) directly improve SourceMedium's accuracy.
+
+We use Shopify as the transactional backbone (financial truth) and enrich it with the best available attribution signals from your entire stack.
+
### What do “Direct / None” & “None / None “ Source / Mediums mean?
`(Direct) / (none)` is the bucket we put things in when we don't have access to attribution data. It means either people visited your website directly (manually typing in the URL) or something outlined above dropped attribution.
@@ -50,4 +73,4 @@ It is also important to note that Google Analytics may not be able to distinguis
Finally, keep in mind that the data provided by GA is only as good as the tracking technology being used, which can be circumvented by customers using ad blockers or faulty tracking. For this reason, we use Shopify as our source of truth and use GA data to enrich that Shopify data.
-**Some of the best practices we have identified are outlined in this [starter doc](https://help.sourcemedium.com/articles/how-can-i-improve-my-last-click-utm-attribution) and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).**
\ No newline at end of file
+**Some of the best practices we have identified are outlined in this [starter doc](/help-center/faq/account-management-faqs/how-can-i-improve-my-last-click-attribution) and this [template](https://docs.google.com/spreadsheets/d/14hx6hlce6zTwfMIcuKLUIuOYl5uWVlcyCr9FIL0GQJk/edit#gid=0).**
diff --git a/help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard.mdx b/help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard.mdx
index d40bc7a..df79d6e 100644
--- a/help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard.mdx
+++ b/help-center/faq/account-management-faqs/why-has-my-amazon-data-stopped-showing-up-in-my-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "Why has my Amazon data stopped showing up in my dashboard?"
+description: "How to troubleshoot and fix Amazon Seller Central MWS token expiration issues that cause data to stop flowing to SourceMedium"
sidebarTitle: "Why has my Amazon data stopped appearing?"
icon: 'question-mark'
---
@@ -25,4 +26,4 @@ If all other data is still flowing in your dashboard, then this is most likely d
1. First, take note of Amazon communications about access renewals. Amazon provides a "Developer Access Renewal" service that reminds you to review developers that have access to your seller account periodically. Check your emails and notifications from Amazon on a regular basis.
2. Second, in your Seller Central account, under **Settings >** **User Permissions** page > [**Manage your Apps**](https://sellercentral.amazon.com/apps/manage) section, you will see a list of developers and apps listed. Click "renew" for "SourceMedium" if Amazon says the access is expiring soon.
----
\ No newline at end of file
+---
diff --git a/help-center/faq/cold-start-guide-home.mdx b/help-center/faq/cold-start-guide-home.mdx
index d379431..8618cf3 100644
--- a/help-center/faq/cold-start-guide-home.mdx
+++ b/help-center/faq/cold-start-guide-home.mdx
@@ -2,18 +2,41 @@
title: "Unsure where to start?"
description: "Follow this resource guide to learn more about SourceMedium"
sidebarTitle: "SourceMedium Cold Start Guide"
+icon: "question-mark"
---
-### Start here 👇
+Use this guide to go from **0 → dashboards + warehouse-ready tables** as quickly as possible.
-[1️⃣ How do I get onboarded to SourceMedium 🗺️](/onboarding/getting-started/getting-started-checklist)
+
+
+ - [What Is SourceMedium?](/help-center/what-is-sourcemedium)
+ - [How your data gets from point A to B](/onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b)
+
-[2️⃣ What is data transformation ⚙️](/data-transformations/philosophy)
+
+ - [Initial onboarding checklist](/onboarding/getting-started/getting-started-checklist)
+ - [All available integrations](/data-inputs/platform-integration-instructions/all-available-integrations)
+
-[3️⃣ What are the included data modules 🖥️](/data-activation/managed-bi-v1/modules/executive-summary-module)
+
+ - [Configuration sheet overview](/data-inputs/configuration-sheet/config-sheet-overview)
+
-[4️⃣ How to use the configuration sheet 📃](/data-inputs/configuration-sheet/config-sheet-overview)
+
+ - [Data Health](/help-center/core-concepts/data-health)
+ - [Attribution Health](/data-inputs/attribution-health/index)
+ - [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+
-[5️⃣ How analytical questions are key to developing a data-driven culture ❓](/onboarding/getting-started/thinking-analytically/how-analytical-questions-are-key)
+
+ - [Dashboard modules index](/data-activation/managed-bi-v1/modules/index)
+ - [Common analytical questions](/onboarding/getting-started/thinking-analytically/common-analytical-questions)
+ - [Data FAQs (reconciliation & mismatches)](/help-center/faq/data-faqs/data-faqs-home)
+ - [AI Analyst (ask questions in Slack)](/ai-analyst/index)
+
-[6️⃣ How to work with the SourceMedium Team 🤝](/onboarding/getting-started/how-to-work-with-the-sourcemedium-team)
+
+ - [Level 1 Data Checklist](/onboarding/getting-started/level-1-data-checklist)
+ - [How to work with the SourceMedium team](/onboarding/getting-started/how-to-work-with-the-sourcemedium-team)
+
+
diff --git a/help-center/faq/configuration-sheet-faqs/configuration-sheet-faqs-home.mdx b/help-center/faq/configuration-sheet-faqs/configuration-sheet-faqs-home.mdx
index 4b565ca..9ad7bd3 100644
--- a/help-center/faq/configuration-sheet-faqs/configuration-sheet-faqs-home.mdx
+++ b/help-center/faq/configuration-sheet-faqs/configuration-sheet-faqs-home.mdx
@@ -1,4 +1,18 @@
---
title: "Configuration Sheet FAQs"
+description: "Frequently asked questions about using the SourceMedium Configuration Sheet for costs, targets, and channel mapping"
sidebarTitle: "Overview"
----
\ No newline at end of file
+icon: "question-mark"
+---
+
+The Configuration Sheet is how you customize SourceMedium reporting without engineering work: mapping channels/subchannels, adding costs, and setting targets.
+
+## Quick links
+
+- [Configuration sheet load frequency](/help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency)
+- [How can I filter out samples, returns, and exchanges?](/help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges)
+
+## Related docs
+
+- [Configuration Sheet overview](/data-inputs/configuration-sheet/config-sheet-overview)
+- [Channel mapping: how does it work?](/data-inputs/configuration-sheet/how_does_channel_mapping_work)
diff --git a/help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency.mdx b/help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency.mdx
index c860721..d5fff27 100644
--- a/help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency.mdx
+++ b/help-center/faq/configuration-sheet-faqs/configuration-sheet-load-frequency.mdx
@@ -1,8 +1,9 @@
---
title: "How soon will I see changes made to my SourceMedium Configuration sheet?"
+description: "Configuration sheet changes are checked every 30 minutes and will appear in your dashboard shortly after"
sidebarTitle: "Configuration Sheet Run Frequency"
icon: 'question-mark'
---
SourceMedium runs a check on your Configuration sheet **every 30 minutes**.
-Any changes that have been made to your Configuration sheet will be surfaced on your dashboard shortly after this check.
\ No newline at end of file
+Any changes that have been made to your Configuration sheet will be surfaced on your dashboard shortly after this check.
diff --git a/help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges.mdx b/help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges.mdx
index cef8240..81d734b 100644
--- a/help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges.mdx
+++ b/help-center/faq/configuration-sheet-faqs/how-can-i-filter-out-samples-returns-and-exchanges.mdx
@@ -1,5 +1,6 @@
---
title: "How can I filter out samples, returns, and exchanges?"
+description: "Using the Configuration Sheet to segment samples, returns, and exchanges into separate channels for cleaner core metrics"
sidebarTitle: "How can I filter out samples, returns, and exchanges?"
icon: 'question-mark'
---
@@ -32,4 +33,4 @@ SourceMedium allows you to sort out these orders into separate `channels` and `s
3. Once the rule(s) have been set in your Configuration sheet, our data model will pick up these new changes after the next data run which occurs each hour
- Any rule(s) set up within the Configuration sheet will work for historical and go forward orders that conform to the rule(s) set in place
----
\ No newline at end of file
+---
diff --git a/help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview.mdx b/help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview.mdx
index 30d27a2..ef48ab9 100644
--- a/help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview.mdx
@@ -1,5 +1,6 @@
---
title: "Amazon - Omnichannel Overview"
+description: "How SourceMedium integrates Amazon sales data alongside DTC channels for unified omnichannel reporting and analysis"
icon: 'question-mark'
---
@@ -8,7 +9,7 @@ icon: 'question-mark'
## Connecting Your Sales Platforms
-We offer several sales platforms as direct integrations. You can find the list and their related instruction articles here at our [Help Site](https://help.sourcemedium.com/integration-docs).
+We offer several sales platforms as direct integrations. You can find the list and their related instruction articles here at our [Help Site](/data-inputs/platform-integration-instructions/all-available-integrations).
## Important Concepts
@@ -26,14 +27,14 @@ The time in which you are looking to analyze a particular set of information. Da
### Definition Differences
-It is important to note that some dimensions and metrics may have different definitions across sales channels. Reviewing the definitions in our [Help Center](https://help.sourcemedium.com/glossary) and [Airtable](https://airtable.com/shrmGxfdCwGRy9QIy/tblkfb5z544UzFuZT) will assist in clarifying any discrepancies that may arise when comparing data across channels.
+It is important to note that some dimensions and metrics may have different definitions across sales channels. Reviewing the definitions in our [Glossary](/help-center/glossary) and [Airtable](https://airtable.com/shrmGxfdCwGRy9QIy/tblkfb5z544UzFuZT) will assist in clarifying any discrepancies that may arise when comparing data across channels.
## How to use SourceMedium for Omnichannel Reporting
-Confirm that SourceMedium has integrated all of your desired sales platforms that we offer direct integration with. Once we have these integrated you will be able to use the **************Channel************** filter located on nearly every module of your dashboard to switch between **************Channel************** views. This allows for a low-friction analysis of each sales channel across several data layers, from customers down to the line item level. For a side-by-side analysis, we offer flexible, pre-built modules and sub-modules within our [Template Gallery](https://lookerstudio.google.com/reporting/2853e13c-3071-44dd-8e24-8f9d6f68381c).
+Confirm that SourceMedium has integrated all of your desired sales platforms that we offer direct integration with. Once we have these integrated you will be able to use the **Channel** filter located on nearly every module of your dashboard to switch between **Channel** views. This allows for a low-friction analysis of each sales channel across several data layers, from customers down to the line item level. For a side-by-side analysis, we offer flexible, pre-built modules and sub-modules within our [Template Gallery](https://lookerstudio.google.com/reporting/2853e13c-3071-44dd-8e24-8f9d6f68381c).

## Getting Help
-If you have any questions or issues while using SourceMedium, please refer to our [Help Center](https://help.sourcemedium.com/) or contact our CSA team via Slack or Email (support@sourcemedium.com) for assistance. We are always here to help you get the most out of your Omnichannel reporting experience.
\ No newline at end of file
+If you have any questions or issues while using SourceMedium, please refer to our [Help Center](/help-center/what-is-sourcemedium) or contact our CSA team via Slack or Email (support@sourcemedium.com) for assistance. We are always here to help you get the most out of your Omnichannel reporting experience.
diff --git a/help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium.mdx b/help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium.mdx
index eee24bd..c7fbbdb 100644
--- a/help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium.mdx
@@ -1,5 +1,6 @@
---
title: "Amazon Sales Performance in SourceMedium"
+description: "Understanding Amazon sales data in SourceMedium including connection setup, key use cases, and platform limitations"
sidebarTitle: "Amazon Sales Performance in SourceMedium"
icon: 'question-mark'
---
@@ -11,7 +12,7 @@ Understanding your sales data is one of the main applications of SourceMedium. T
To access Amazon data in the first place, you'll need to allow SourceMedium to connect and ingest your data.
-[More information about connecting SourceMedium and Amazon can be found here](https://www.notion.so/Amazon-Seller-Central-Connect-to-Source-Medium-f591f3f98d6b448691598f864049c175?pvs=21).
+[More information about connecting SourceMedium and Amazon can be found here](/data-inputs/platform-integration-instructions/amazon-sc-integration).
### Where can I find Amazon Sales Data in SourceMedium?
@@ -101,4 +102,4 @@ Amazon does not share all of their data, so as you navigate you're likely to see
Amazon doesn't offer any source/medium information or acquisition campaign information. This means you won't have CAC (Customer Acquisition Cost), although you will see CPA (as spend / new customers)
-For a full list of Amazon data availability, consult [this airtable](https://airtable.com/apptitEI5nyySjQPN/tblkfb5z544UzFuZT/viwRQeASMv6JHro1M?blocks=hide).
\ No newline at end of file
+For a full list of Amazon data availability, consult [this airtable](https://airtable.com/apptitEI5nyySjQPN/tblkfb5z544UzFuZT/viwRQeASMv6JHro1M?blocks=hide).
diff --git a/help-center/faq/dashboard-functionality-faqs/dashboard-functionality-faqs-home.mdx b/help-center/faq/dashboard-functionality-faqs/dashboard-functionality-faqs-home.mdx
index 95dc174..1c656e3 100644
--- a/help-center/faq/dashboard-functionality-faqs/dashboard-functionality-faqs-home.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/dashboard-functionality-faqs-home.mdx
@@ -1,4 +1,21 @@
---
title: "Dashboard Functionality FAQs"
+description: "Frequently asked questions about using your SourceMedium dashboard, modules, filters, and report features"
sidebarTitle: "Overview"
----
\ No newline at end of file
+icon: "question-mark"
+---
+
+This section covers how to use your SourceMedium dashboard (filters, modules, and common behaviors) and where to find specific reporting views.
+
+## Amazon reporting
+
+- [Amazon Omnichannel Overview](/help-center/faq/dashboard-functionality-faqs/amazon-omnichannel-overview)
+- [Amazon Sales Performance in SourceMedium](/help-center/faq/dashboard-functionality-faqs/amazon-sales-performance-in-sourcemedium)
+- [Where can I find my Amazon marketing data?](/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data)
+- [Where can I find my Amazon LTV?](/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv)
+- [Where can I find my Amazon product performance?](/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance)
+
+## Common dashboard behavior
+
+- [How does editing an order after the order date affect reporting?](/help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting)
+- [What is the "Exclude \$0 Orders" feature?](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
diff --git a/help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting.mdx b/help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting.mdx
index d21f484..8c09f45 100644
--- a/help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/how-does-editing-an-order-after-the-order-date-affect-reporting.mdx
@@ -1,5 +1,6 @@
---
title: "How does editing an order after the order date affect reporting?"
+description: "How SourceMedium handles order modifications differently than Shopify's transaction-based reporting and why revenue may differ"
sidebarTitle: "Does editing post-order date affect reporting?"
icon: 'question-mark'
---
@@ -27,4 +28,4 @@ A customer places an order of \$100 on November 10th from Store XYZ. The same cu
| Nov 10, 2022 | \$150.00 |
| Nov 11, 2022 | - |
-
\ No newline at end of file
+
diff --git a/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration.mdx b/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration.mdx
index 4335a63..117641a 100644
--- a/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/what-are-the-implications-of-the-new-amazon-sp-api-integration.mdx
@@ -1,5 +1,6 @@
---
title: "What are the implications of the new (BETA) Amazon SP-API integration?"
+description: "Benefits and features of the Amazon Selling Partner API integration for omnichannel reporting in SourceMedium"
sidebarTitle: "Implications of the Amazon SP-API Integration"
icon: 'question-mark'
---
@@ -12,7 +13,7 @@ Amazon deprecated their MWS reporting API and transitioned to SP (Selling Partne
### What is the benefit of integrating Amazon data into the dashboard?
- Increase your omni-channel awareness by blending Amazon sales into your Executive Summary
-- Determine and compare Amazon acquisition performance (when [Amazon Ads](https://help.sourcemedium.com/articles/connect-amazon-ads-data-to-source-medium-dashboards) also integrated)
+- Determine and compare Amazon acquisition performance (when [Amazon Ads](/data-inputs/platform-integration-instructions/amazon-ads-integration) also integrated)
### What Amazon data will surface in the dashboard?
@@ -85,6 +86,6 @@ If have any questions or feedback about this beta integration, let us know using
### **Additional information and related articles**
-- [Amazon (SP) integration instructions](https://help.sourcemedium.com/articles/connect-amazon-seller-central-data-to-source-medium)
-- [Amazon Ads integration instructions](https://help.sourcemedium.com/articles/connect-amazon-ads-data-to-source-medium-dashboards)
-- [Amazon [BETA] Integration Feedback Form](https://form.jotform.com/223005113695145)
\ No newline at end of file
+- [Amazon (SP) integration instructions](/data-inputs/platform-integration-instructions/amazon-sc-integration)
+- [Amazon Ads integration instructions](/data-inputs/platform-integration-instructions/amazon-ads-integration)
+- [Amazon [BETA] Integration Feedback Form](https://form.jotform.com/223005113695145)
diff --git a/help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature.mdx b/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature.mdx
similarity index 83%
rename from help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature.mdx
rename to help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature.mdx
index 118dde5..3e6c151 100644
--- a/help-center/faq/dashboard-functionality-faqs/what-is-exclude-$0-feature.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature.mdx
@@ -1,5 +1,6 @@
---
title: "What is the Exclude $0 Order feature?"
+description: "How the Exclude $0 Orders feature removes zero-revenue orders from Executive Summary and Retention reporting to improve acquisition metric accuracy"
icon: 'question-mark'
---
@@ -38,7 +39,7 @@ There are many scenarios in which an order could come out to a Total Revenue of
- fully discounted orders
- free promo / gift orders
-These orders aren't necessarily useful - and in some situations should be removed from the picture - to ensure the most accurate analyses. Consider the [example in the section above](https://www.notion.so/Exclude-0-Orders-feature-what-s-it-for-cb55795a3e694a2bb019181502f8f6e7?pvs=21) - having a fully refunded order inflated ROAS vs removing that order from the equation, due to lower net revenue with that order included. CPO was similarly impacted, but to a more extreme degree - CPO was \$50 with the refunded order included, compared to having it excluded with a CPO of \$56.
+These orders aren't necessarily useful - and in some situations should be removed from the picture - to ensure the most accurate analyses. Consider the example in the section above: having a fully refunded order can inflate ROAS vs removing that order from the equation, due to lower net revenue with that order included. CPO can be similarly impacted.
Depending on which view of macro-level KPIs you consider to be “pure” (from the above example), should inform whether or not you should enable the Exclude \$0 Orders feature.
@@ -49,4 +50,4 @@ Depending on which view of macro-level KPIs you consider to be “pure” (from
### Additional information and related articles
-- [Why isn't my revenue in the Executive Summary matching with Shopify's Sales Report?](https://www.notion.so/Why-don-t-the-Executive-Summary-and-Shopify-s-Sales-Report-match-32bcf5812cde45c893b02ddfcb63815e?pvs=21)
\ No newline at end of file
+- [Why don't the Executive Summary and Shopify's Sales Report match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
diff --git a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv.mdx b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv.mdx
index 6613892..4eab155 100644
--- a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-ltv.mdx
@@ -1,5 +1,6 @@
---
title: "Where can I find my Amazon LTV?"
+description: "How to access Amazon customer lifetime value and retention metrics in your SourceMedium dashboard using the channel filter"
sidebarTitle: "Where can I find my Amazon LTV?"
icon: 'question-mark'
---
@@ -35,4 +36,4 @@ Under the **Acquisition Order Filter Type** for Amazon, there are options to see
*Note: the acquisition order type filter allows you to filter cohorts based on their first/acquisition order. Any subsequent orders may not fit the same profile as the acquisition order (e.g a different product may be purchased). The filters are sorted by the max cohort size (defined by the max cohort month).*
-
\ No newline at end of file
+
diff --git a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data.mdx b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data.mdx
index d31e2a6..27ea495 100644
--- a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-marketing-data.mdx
@@ -1,12 +1,13 @@
---
title: "Were can I find my Amazon marketing data?"
+description: "Locate Amazon Ads and Amazon DSP performance data in the SourceMedium Marketing Overview dashboard"
icon: 'question-mark'
---
-The **Marketing Overview Page** is the hub for all of your directly integrated marketing platforms, [manually input marketing costs](https://help.sourcemedium.com/articles/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet), and [influencer cost/performance](https://help.sourcemedium.com/articles/tracking-influencer-performance-using-your-source-medium-configuration-sheet-cost-tab). This includes both your Amazon Ads and Amazon DSP data!
+The **Marketing Overview Page** is the hub for all of your directly integrated marketing platforms, [manually input marketing costs](/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet), and [influencer cost/performance](/data-inputs/configuration-sheet/how-can-i-track-influencer-spend-and-performance). This includes both your Amazon Ads and Amazon DSP data!
-### Connecting your Amazon Ads and DSP Accounts to Source Medium
+### Connecting your Amazon Ads and DSP Accounts to SourceMedium
-Follow our Integration Documents to learn how to connect your [Amazon Ads Data](https://help.sourcemedium.com/integration-docs/connect-amazon-ads-data-to-source-medium-dashboards) and [Amazon DSP Data](https://help.sourcemedium.com/articles/amazon-dsp-connect-to-source-medium) with SourceMedium.
+Follow our Integration Documents to learn how to connect your [Amazon Ads Data](/data-inputs/platform-integration-instructions/amazon-ads-integration) and [Amazon DSP Data](/data-inputs/platform-integration-instructions/amazon-dsp-integration) with SourceMedium.
### Finding the Marketing Overview Page
@@ -40,7 +41,7 @@ This allows you to narrow your results to just the date range you desire.
You can see your Amazon data alongside Online DTC by clicking the checkbox to include Amazon marketing data
- To see your Amazon marketing data alone *******(as shown below),******* click the ONLY button next to the `Amazon` option.
+ To see your Amazon marketing data alone (as shown below), click the ONLY button next to the `Amazon` option.

Accordion>
@@ -136,7 +137,7 @@ Once you have selected your desired filters, the Marketing Overview is easy to n
These performance graphs also allow you to change the performance metric shown. Click Optional Metrics button to select your desired performance metric
- *************************************The bar graphs default to Spend and the time-series line graphs default to ROAS*************************************
+ The bar graphs default to Spend and the time-series line graphs default to ROAS.

@@ -151,7 +152,7 @@ Campaign Performance by Spend & Conversions groups campaigns from the same platf
AccordionGroup>
### Where Else Does Your Amazon Marketing Data Surface?
-The same marketing data from the Marketing Overview page also surfaces in the Executive section of your Dashboard. It is sourced from your Amazon marketing connections as well as any additional spend attributed to Amazon in the Cost tab of your Configuration Sheet ([find out how to do so here](https://help.sourcemedium.com/articles/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet)).
+The same marketing data from the Marketing Overview page also surfaces in the Executive section of your Dashboard. It is sourced from your Amazon marketing connections as well as any additional spend attributed to Amazon in the Cost tab of your Configuration Sheet ([find out how to do so here](/data-inputs/configuration-sheet/how-do-i-include-marketing-spend-through-the-cost-tab-of-the-configuration-sheet)).
Just make sure to select the proper date range and set the `Channel` filter to include `Amazon` data, as it defaults to `Online DTC` alone.
@@ -196,4 +197,4 @@ Just make sure to select the proper date range and set the `Channel` filter to i
1. After connecting us to your marketing accounts, we will integrate your marketing information to our data models. Due to Amazon's imposed API limitations, historic Ads and DSP data is limited to 60 days before the initial ingestion. **The sooner you connect us to your Amazon Ads and DSP data, the more historic data will be available and stored in your dashboard.**
2. We guarantee data freshness to 72 hours before the present, but it is typically fresh to 48 hours.
-3. We are currently using "total purchases" as the metric for conversions, with a 14 day window for DSP.
\ No newline at end of file
+3. We are currently using "total purchases" as the metric for conversions, with a 14 day window for DSP.
diff --git a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance.mdx b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance.mdx
index ecdc840..949d379 100644
--- a/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/where-can-i-find-my-amazon-product-performance.mdx
@@ -1,9 +1,10 @@
---
title: "Where can I find my Amazon product performance?"
+description: "Navigate to Amazon product analytics in SourceMedium's Product Performance module using the channel filter"
sidebarTitle: "Amazon Product Performance"
icon: 'question-mark'
---
-This article is designed to provide high-level instruction on evaluating your individual product performance from Amazon within Source Medium. Let's dive in and unlock the potential of your products on Amazon!
+This article is designed to provide high-level instruction on evaluating your individual product performance from Amazon within SourceMedium. Let's dive in and unlock the potential of your products on Amazon!
To get to the module, on the sidebar of the report, there will be a **Orders & Products** section that can be clicked on. After clicking on that section, it will populate these options:
@@ -54,4 +55,4 @@ Click on the filter and select only **Amazon** to get to the Amazon product perf
#### Refunds
- Refunds could be lagged by at least one week due to the factors of variables such as shipping times, customer-reported refund times and amazon reporting times.
\ No newline at end of file
+ Refunds could be lagged by at least one week due to the factors of variables such as shipping times, customer-reported refund times and amazon reporting times.
diff --git a/help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report.mdx b/help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report.mdx
index f6fe0c4..e48a337 100644
--- a/help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report.mdx
+++ b/help-center/faq/dashboard-functionality-faqs/why-does-my-ltv-look-off-in-my-multi-store-report.mdx
@@ -1,5 +1,6 @@
---
title: "Why does my LTV look off in my multi-store report?"
+description: "Why LTV and Retention reports must be viewed per-store and don't support cross-brand holistic calculations"
icon: 'question-mark'
---
**Environmental factors:** Multiple Shopify stores
@@ -7,4 +8,4 @@ icon: 'question-mark'
### Resolution ###
For LTV and Retention reports, make sure you only have one brand selected in the Brand ID filter. Currently, we do not support cross-brand holistic LTV (e.g. combining multiple stores at the same time and looking at the LTV). LTV needs to be viewed on a per-store basis.
----
\ No newline at end of file
+---
diff --git a/help-center/faq/data-faqs/data-faqs-home.mdx b/help-center/faq/data-faqs/data-faqs-home.mdx
index 6111dce..57a28ca 100644
--- a/help-center/faq/data-faqs/data-faqs-home.mdx
+++ b/help-center/faq/data-faqs/data-faqs-home.mdx
@@ -1,4 +1,26 @@
---
title: "Data FAQs"
+description: "Frequently asked questions about data discrepancies, metric definitions, and how SourceMedium calculates key business metrics"
sidebarTitle: "Overview"
----
\ No newline at end of file
+icon: "question-mark"
+---
+
+Use this section when you’re comparing SourceMedium to another system (Shopify, ReCharge, ad platforms, GA4) and you’re trying to understand why numbers don’t match.
+
+## Start here
+
+- Confirm you’re comparing the same date range, store(s), and channel(s).
+- Check whether your brand has special handling enabled (for example, excluding \$0 orders).
+
+## Common questions
+
+- [Why would external reports not match the SourceMedium dashboard?](/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard)
+- [Why don't the Executive Summary and Shopify's Sales Report match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
+- [Why doesn't ReCharge subscription data match SourceMedium reports?](/help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium)
+- [What impact does Global-E have in SourceMedium?](/help-center/faq/account-management-faqs/what-impact-does-global-e-have-in-source-medium)
+- [What attribution windows does SourceMedium report on for marketing platforms?](/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms)
+- [How does Stripe metadata work?](/help-center/faq/data-faqs/how-does-stripe-metadata-work)
+
+## Related dashboard behavior
+
+- [What is the "Exclude \$0 Orders" feature?](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
diff --git a/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report.mdx b/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report.mdx
deleted file mode 100644
index d72da6d..0000000
--- a/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Why isn't my revenue in the Executive Summary matching with Shopify's Sales Report?"
----
-
-The Executive Summary is designed to mirror the accounting rules present in the Shopify Sales Report, and will almost always
-match 1:1. However, there are some instances where you won't see a 1:1 match:
-
-1. If your brand has our `Exclude $0 Orders` feature enabled, you will see a revenue and orders mismatch. This feature excludes
-orders with a total revenue of $0 from all Executive Summary and Retention dashboard data. If you're unsure if you have this
-feature enabled, reach out to our Support team in Slack or via email at support@sourcemedium.com. See here for a deeper explanation of this feature
-
-2. If your brand has any data cleaning rules in the Channel Mapping tab your Configuration Sheet-- e.g. any rules routing orders
-to a channel other than Online DTC -- you will see a mismatch if only Online DTC is selected in the channel dropdown (located at
-the top right-hand corner of your report, under the date range filter).
-
-If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between
-the Executive Summary and Shopify Sales report
\ No newline at end of file
diff --git a/help-center/faq/data-faqs/how-does-stripe-metadata-work.mdx b/help-center/faq/data-faqs/how-does-stripe-metadata-work.mdx
index b4f9da7..9157149 100644
--- a/help-center/faq/data-faqs/how-does-stripe-metadata-work.mdx
+++ b/help-center/faq/data-faqs/how-does-stripe-metadata-work.mdx
@@ -1,5 +1,6 @@
---
title: "How does Stripe metadata work?"
+description: "How to enrich Stripe charge objects with custom metadata for accurate product and order-level reporting in SourceMedium"
icon: 'question-mark'
---
@@ -25,40 +26,42 @@ The following data should be provided via the metadata in each charge in JSON fo
-```sql
+```json
{
-"order_id": "order-id-123", # as order_id_secondary
- "subscription_id": "subscription-id-123", # if applicable
- "order_type": "onetime|first_sub_order|recurring_sub_order|trial", # required
+ "order_id": "order-id-123",
+ "subscription_id": "subscription-id-123",
+ "order_type": "onetime|first_sub_order|recurring_sub_order",
"line_items": [
- {
- "line_item_id": "order-line-id-123", # required
- "sku": "SKU123", # required
- "product_title": "Awesome Product", # optional
- "variant_title": "2 Pack", # optional
- "price": 12, # required
- "quantity": 2, # required
- "gross_revenue": 24, # 12 * 2
- "net_revenue": 20, # gross - discounts - refunds
- "total_discounts": 4 # required
- }
- ], # required
- "refund_line_items": [ # ONLY relevant if there's a refund on this charge.
- "line_item_id": "order-line-id-123", # required
- "subtotal": "{{ REFUNDED AMOUNT }}" # required
- ],
- "discount_code": "WELCOME15",
- "shipping_city": "{{CITY}}",
- "shipping_state": "{{STATE}}",
- "shipping_country": "{{COUNTRY}}",
- "shipping_zip": "{{ZIP}}",
- "zero_party_attribution": "YouTube - Ads - {{ Account Name }}",
- "utm_source": "{{ utm_source }}",
- "utm_medium": "{{ utm_medium }}",
- "utm_campaign": "{{ utm_campaign }}",
- "utm_term": "{{ utm_term }}",
- "utm_content": "{{ utm_content }}",
- "tags": "tag1, tag2, tag3"
+ {
+ "line_item_id": "order-line-id-123",
+ "sku": "SKU123",
+ "product_title": "Awesome Product",
+ "variant_title": "2 Pack",
+ "price": 12,
+ "quantity": 2,
+ "gross_revenue": 24,
+ "net_revenue": 20,
+ "total_discounts": 4
+ }
+ ],
+ "refund_line_items": [
+ {
+ "line_item_id": "order-line-id-123",
+ "subtotal": "{{REFUNDED_AMOUNT}}"
+ }
+ ],
+ "discount_code": "WELCOME15",
+ "shipping_city": "{{CITY}}",
+ "shipping_state": "{{STATE}}",
+ "shipping_country": "{{COUNTRY}}",
+ "shipping_zip": "{{ZIP}}",
+ "zero_party_attribution": "youtube - ads - {{ACCOUNT_NAME}}",
+ "utm_source": "{{UTM_SOURCE}}",
+ "utm_medium": "{{UTM_MEDIUM}}",
+ "utm_campaign": "{{UTM_CAMPAIGN}}",
+ "utm_term": "{{UTM_TERM}}",
+ "utm_content": "{{UTM_CONTENT}}",
+ "tags": "tag1, tag2, tag3"
}
```
@@ -79,4 +82,4 @@ The following data should be provided via the metadata in each charge in JSON fo
- Orders Deep Dive
- Product Performance
- Retention/LTV
-- Product Affinity
\ No newline at end of file
+- Product Affinity
diff --git a/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedoum-report-on-for-marketing-platforms.mdx b/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms.mdx
similarity index 79%
rename from help-center/faq/data-faqs/what-attribution-windows-does-sourcemedoum-report-on-for-marketing-platforms.mdx
rename to help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms.mdx
index 8e181ed..e26f379 100644
--- a/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedoum-report-on-for-marketing-platforms.mdx
+++ b/help-center/faq/data-faqs/what-attribution-windows-does-sourcemedium-report-on-for-marketing-platforms.mdx
@@ -1,8 +1,9 @@
---
title: "What attribution windows does SourceMedium report on for marketing platforms?"
+description: "How SourceMedium uses the attribution windows configured in your ad platforms like Meta, Google Ads, Snapchat, and TikTok"
sidebarTitle: "What marketing attribution windows does SM use?"
icon: 'question-mark'
---
For all marketing platforms, SourceMedium will report on the attribution window set within your ad platform.
-For example, if you haven't changed your Snapchat Ads attribution window, we will use the default 28-day click, 1-day view window. If you update your Snapchat configuration to a different attribution window, we will report on the new window. For Meta, SourceMedium will report based on an account-level default of 7-day click, 1-day view.
\ No newline at end of file
+For example, if you haven't changed your Snapchat Ads attribution window, we will use the default 28-day click, 1-day view window. If you update your Snapchat configuration to a different attribution window, we will report on the new window. For Meta, SourceMedium will report based on an account-level default of 7-day click, 1-day view.
diff --git a/help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview.mdx b/help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview.mdx
index 25efcb9..1c90fd1 100644
--- a/help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview.mdx
+++ b/help-center/faq/data-faqs/what-is-reported-as-a-conversion-within-the-marketing-overview.mdx
@@ -1,5 +1,6 @@
---
-title: "What is reported as a “conversion” within the Marketing Overview?"
+title: 'What is reported as a "conversion" within the Marketing Overview?'
+description: "How SourceMedium defines conversions for each marketing platform including Google Ads, Meta, TikTok, Bing, and Pinterest"
sidebarTitle: "Marketing Overview conversion definition"
icon: 'question-mark'
---
@@ -56,4 +57,3 @@ Below are our platform-specific definitions for what is counted as a Conversion
---
-
diff --git a/help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium.mdx b/help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium.mdx
new file mode 100644
index 0000000..e77977f
--- /dev/null
+++ b/help-center/faq/data-faqs/why-doesnt-recharge-match-sourcemedium.mdx
@@ -0,0 +1,49 @@
+---
+title: "Why doesn't ReCharge subscription data match SourceMedium reports?"
+description: "Common reasons ReCharge subscription reporting can differ from SourceMedium dashboards and how to troubleshoot"
+sidebarTitle: "Why ReCharge doesn't match"
+icon: "question-mark"
+---
+
+It’s common for subscription reporting to differ across tools. ReCharge and SourceMedium may be answering slightly different questions, using different timestamps, or applying different rules for refunds, cancellations, and attribution.
+
+## Start by aligning on definitions
+
+Before troubleshooting, confirm which definition you’re using in each tool:
+
+- **New subscriptions:** created date vs first successful charge vs first fulfilled order
+- **Cancelled subscriptions:** cancelled timestamp vs churn proxy (no recurring orders in X days)
+- **Subscription order revenue:** gross vs net revenue, and how refunds are handled
+
+## Common causes of mismatches
+
+### 1) Different time fields
+
+ReCharge often reports on subscription lifecycle timestamps, while SourceMedium reporting typically uses order-based timestamps (e.g., processed/created at) for revenue and order metrics.
+
+### 2) Refund and cancellation handling
+
+If an order is refunded or cancelled, different tools may:
+
+- Exclude it entirely
+- Include it in gross but not net
+- Attribute it to the original purchase date vs the refund date
+
+### 3) Attribution differences (UTM + checkout)
+
+Subscription checkouts can reduce UTM coverage depending on your storefront/checkout setup. If you’re validating “source/medium” or channel attribution, start with:
+
+- [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+- [Google Analytics common failures](/data-inputs/platform-supporting-resources/ga4/google-analytics-common-failures)
+
+### 4) Multi-store / multi-channel scoping
+
+Confirm you’re comparing the same store(s), channel(s), and date range in both tools.
+
+## What to do next
+
+If you’re still seeing unexplained differences, share the following with your SourceMedium team:
+
+- The ReCharge report you’re using (name + filters + date field)
+- The SourceMedium module/table you’re comparing against
+- A handful of example subscription IDs or order IDs that illustrate the mismatch
diff --git a/help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers.mdx b/help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers.mdx
index 30328a2..e10e236 100644
--- a/help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers.mdx
+++ b/help-center/faq/data-faqs/why-dont-new-customers-plus-repeat-customers-equal-customers.mdx
@@ -1,5 +1,6 @@
---
title: "Why don't New Customers + Repeat Customers = Customers?"
+description: "Understanding how SourceMedium counts new and repeat customers independently, and why the sum can exceed total customers"
icon: 'question-mark'
---
### Executive Summary ###
@@ -39,4 +40,4 @@ If a customer buys 3 orders in July, the customer is counted once as a New Custo
| Last Order Analysis | Absolute | If a customer buys once in July and twice in August, the customer is counted once in August on the date of the third purchase and categorized as Repeat Purchaser.
If a customer buys 3 times in July, the customer is counted once on the date of the third purchase and categorized as Repeat Purchaser. |
----
\ No newline at end of file
+---
diff --git a/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match.mdx b/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match.mdx
index 3596e9e..8ffbd46 100644
--- a/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match.mdx
+++ b/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match.mdx
@@ -1,5 +1,6 @@
---
title: "Why don't the Executive Summary and Shopify's Sales Report match?"
+description: "Common reasons for differences between SourceMedium Executive Summary and Shopify Sales Report including exclude $0 orders and channel mapping"
sidebarTitle: "Why don't Executive Summary & Shopify match?"
icon: 'question-mark'
---
@@ -7,8 +8,8 @@ The Executive Summary is designed to mirror the accounting rules present in the
1. If your brand has our **'Exclude \$0 Orders' feature** enabled, you will see a revenue and orders mismatch. This feature excludes orders with a `total revenue` of \$0 from all Executive Summary and Retention dashboard data. If you're unsure if you have this feature enabled, reach out to our Support team in Slack or via email at support@sourcemedium.com.
- - [See here for a deeper explanation of this feature](https://www.notion.so/Exclude-0-Orders-feature-what-s-it-for-cb55795a3e694a2bb019181502f8f6e7?pvs=21)
+ - [See here for a deeper explanation of this feature](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
2. If your brand has **any data cleaning rules in the Channel Mapping tab your Configuration Sheet**-- e.g. any rules routing orders to a channel other than Online DTC -- you will see a mismatch if only Online DTC is selected in the `channel` dropdown (located at the top right-hand corner of your report, under the date range filter).
- - **If you are running sales through Amazon, be sure to deselect "Amazon" in the `channel` dropdown** when comparing sales data between the Executive Summary and Shopify Sales report.
\ No newline at end of file
+ - **If you are running sales through Amazon, be sure to deselect "Amazon" in the `channel` dropdown** when comparing sales data between the Executive Summary and Shopify Sales report.
diff --git a/help-center/faq/data-faqs/why-is-my-data-taking-so-long-to-load.mdx b/help-center/faq/data-faqs/why-is-my-data-taking-so-long-to-load.mdx
new file mode 100644
index 0000000..da46e04
--- /dev/null
+++ b/help-center/faq/data-faqs/why-is-my-data-taking-so-long-to-load.mdx
@@ -0,0 +1,43 @@
+---
+title: "Why is my data taking so long to load?"
+sidebarTitle: "Data taking long to load"
+description: "Understanding why historical data ingestion can take longer for high-volume stores"
+icon: "clock"
+---
+
+If your SourceMedium dashboard isn't showing data yet, or you're waiting longer than expected, here's what's likely happening.
+
+## The short answer
+
+**Data volume determines ingestion time.** The more historical data your store has, the longer full ingestion takes. Your SourceMedium contact can give you a specific estimate based on your data volume.
+
+## What affects ingestion time?
+
+The main factors are:
+
+- **Order count** — The primary driver. More orders = more data to process.
+- **Line items per order** — Stores with high average cart sizes have more data per order.
+- **Customer count** — A large customer database adds to total data volume.
+- **Historical depth** — 10 years of data takes longer than 2 years.
+
+## What can I do?
+
+### Check with your SourceMedium contact
+
+They can give you a status update and estimated completion time.
+
+### Consider a phased approach
+
+If you have a specific go-live deadline and your data volume is very high, we can discuss starting with recent data (e.g., last 1-2 years) while full history loads in the background.
+
+
+**Trade-off:** Starting with partial history means LTV calculations will only reflect the loaded period. A customer who first purchased 5 years ago would appear as a "new" customer if we only loaded 2 years. Once full history loads, everything updates automatically.
+
+
+### For future onboardings
+
+If you manage multiple stores or brands, running a [Data Volume Assessment](/onboarding/getting-started/data-volume-assessment) before integration helps set accurate timeline expectations upfront.
+
+## Still have questions?
+
+Reach out to your SourceMedium contact via Slack or email support@sourcemedium.com.
diff --git a/help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue.mdx b/help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue.mdx
index b542c8e..f4bc2b8 100644
--- a/help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue.mdx
+++ b/help-center/faq/data-faqs/why-isnt-the-executive-summary-report-attributing-my-gift-card-revenue.mdx
@@ -1,8 +1,9 @@
---
title: "Why isn't the Executive Summary report attributing my gift card revenue?"
+description: "Why gift card purchases are treated as deferred revenue in SourceMedium and how to analyze gift card data"
sidebarTitle: "Exectuive Summary not showing gift card revenue"
icon: 'question-mark'
---
Gift card revenue is not counted towards revenue because revenue from gift cards is considered deferred revenue. To analyze gift card revenue you can use the `Payment Gateway` filter on the Orders Deep Dive module. Revenue from gift cards will be tracked when the gift cards are spent.
-**Additional Note:** First-time orders which include only gift cards are not counted as new customers by Shopify, but will be counted as new customers by SourceMedium.
\ No newline at end of file
+**Additional Note:** First-time orders which include only gift cards are not counted as new customers by Shopify, but will be counted as new customers by SourceMedium.
diff --git a/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard.mdx b/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard.mdx
index 1206c59..ebb37a9 100644
--- a/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard.mdx
+++ b/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard.mdx
@@ -1,5 +1,6 @@
---
title: "Why would external reports not match the SourceMedium dashboard?"
+description: "Common reasons for data discrepancies between SourceMedium and Shopify, Meta Ads, Google Ads, or other external reporting tools"
sidebarTitle: "External reports don't match SourceMedium - commmon causes"
icon: 'question-mark'
---
@@ -31,4 +32,4 @@ Often caused by Facebook or Google dynamically taking credit for purchases happe
SourceMedium is Source of Truth reporting, which means the data that is surfaced is pulled raw from the data source/platform, transformed, and then provided for the BI layer (Looker Studio dashboard, or BYOBI)
----
\ No newline at end of file
+---
diff --git a/help-center/faq/faq-imports/faq-import-template.mdx b/help-center/faq/faq-imports/faq-import-template.mdx
deleted file mode 100644
index a024c20..0000000
--- a/help-center/faq/faq-imports/faq-import-template.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Question?"
-icon: 'question-mark'
----
-
diff --git a/help-center/glossary.mdx b/help-center/glossary.mdx
new file mode 100644
index 0000000..20534ab
--- /dev/null
+++ b/help-center/glossary.mdx
@@ -0,0 +1,69 @@
+---
+title: "Glossary"
+description: "Definitions for common SourceMedium terms used across dashboards, tables, and FAQs"
+icon: "book"
+---
+
+This page defines common terms you’ll see throughout SourceMedium documentation. If you’re reconciling numbers across tools, start by aligning on these definitions.
+
+## Channel
+
+A **channel** is a standardized classification used to group orders and performance (e.g., Online DTC, Amazon). Channel values can be influenced by configuration sheet mapping rules.
+
+Related:
+
+- [How does channel mapping work?](/data-inputs/configuration-sheet/how_does_channel_mapping_work)
+- [Why would external reports not match the SourceMedium dashboard?](/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard)
+
+## Subchannel
+
+A **subchannel** is a more granular breakdown under a channel (for example, different paid social strategies, affiliates, marketplaces, etc.). Subchannels are typically defined via channel mapping rules and/or UTMs.
+
+## SourceMedium-valid order
+
+A **SourceMedium-valid** order is an order that should be included in reporting (excluding test/invalid/voided scenarios). For order-based analyses, start with `is_order_sm_valid = TRUE`.
+
+See: [`obt_orders`](/data-activation/data-tables/sm_transformed_v2/obt_orders)
+
+## Gross revenue vs net revenue
+
+- **Gross revenue** is typically line-level price × quantity, before discounts/refunds.
+- **Net revenue** accounts for discounts/refunds and is usually the preferred basis for profitability and LTV analyses.
+
+If you’re reconciling to Shopify, see: [Why don’t Executive Summary & Shopify match?](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match)
+
+## Exclude $0 orders
+
+Some accounts exclude $0 revenue orders from reporting. This can impact reconciliations and retention metrics.
+
+See: [What is exclude $0 orders?](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature)
+
+## Attribution window
+
+An **attribution window** defines how far back in time a marketing interaction can receive credit for a purchase (e.g., 7-day click, 28-day click, 120-day lookback). Different tools often use different windows.
+
+See: [Attribution in SourceMedium](/help-center/core-concepts/attribution/attribution-in-sourcemedium)
+
+## UTM parameters
+
+**UTM parameters** are tracking parameters added to URLs (for example: `utm_source`, `utm_medium`, `utm_campaign`) to attribute traffic and purchases to marketing campaigns.
+
+See: [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+
+## (direct) / (none)
+
+**`(direct) / (none)`** typically means no attributable marketing touchpoint was captured for an order (often due to missing UTMs, cross-domain/checkout breaks, or tracking blockers).
+
+See: [Why am I seeing (direct) / (none)?](/help-center/core-concepts/attribution/direct-none) and [Attribution Health](/data-inputs/attribution-health/index)
+
+## First-party attribution
+
+**First-party attribution** uses data you collect and control from your own properties (your site/app and checkout) to understand marketing touchpoints.
+
+See: [First-Party Attribution](/help-center/core-concepts/attribution/first-party-attribution)
+
+## Zero-party attribution
+
+**Zero-party attribution** uses customer-reported answers (like “How did you hear about us?”) to understand discovery channels that tracking often misses.
+
+See: [Zero-Party Attribution](/help-center/core-concepts/attribution/zero-party-attribution)
diff --git a/help-center/loom-vid-embed-test.mdx b/help-center/loom-vid-embed-test.mdx
deleted file mode 100644
index 2c9c59c..0000000
--- a/help-center/loom-vid-embed-test.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
-# test
-
-Created by: Sam Thurman
-Status: Ready to Scope
-Assign: Sam Thurman
-Date added: December 12, 2023 10:48 AM
-Last Edited: December 12, 2023 10:49 AM
-
-## This is a video from Loom
-
-
\ No newline at end of file
diff --git a/help-center/raw-data-source-overviews/amazon-sc-overview.mdx b/help-center/raw-data-source-overviews/amazon-sc-overview.mdx
index a06831a..3afced3 100644
--- a/help-center/raw-data-source-overviews/amazon-sc-overview.mdx
+++ b/help-center/raw-data-source-overviews/amazon-sc-overview.mdx
@@ -1,7 +1,24 @@
---
title: 'Amazon Seller Central'
-description: ''
+description: "What SourceMedium ingests from Amazon Seller Central and common caveats when validating Amazon sales reporting"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium integrates Amazon Seller Central data to support unified omnichannel reporting alongside DTC channels.
+
+## What we ingest
+
+- Orders and sales reporting (including historical backfill, where available)
+- Refunds/returns (with platform-specific reporting delays)
+- Product identifiers and order-level metadata used for reporting
+
+## Common caveats
+
+- Amazon reporting often has delays and retroactive changes (especially for FBA returns).
+- Historical reporting can differ from real-time/enriched feeds depending on what Amazon exposes.
+
+See: [Amazon Seller Central: Data nuances & limitations](/data-inputs/platform-supporting-resources/amazon-seller-central/amazon-sc-data-nuances-and-limitations)
+
+## Setup
+
+- [Amazon Seller Central integration instructions](/data-inputs/platform-integration-instructions/amazon-sc-integration)
diff --git a/help-center/raw-data-source-overviews/chargebee-overview.mdx b/help-center/raw-data-source-overviews/chargebee-overview.mdx
index 90fee19..1667159 100644
--- a/help-center/raw-data-source-overviews/chargebee-overview.mdx
+++ b/help-center/raw-data-source-overviews/chargebee-overview.mdx
@@ -1,7 +1,17 @@
---
title: 'Chargebee'
-description: ''
+description: "What SourceMedium ingests from Chargebee and how to validate key subscription and revenue fields"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium can integrate Chargebee to support subscription revenue and subscriber analytics.
+
+## Setup
+
+- [Chargebee integration instructions](/data-inputs/platform-integration-instructions/chargebee-integration)
+
+## What to validate
+
+- Subscriber counts vs your source platform
+- Recurring vs one-time revenue definitions
+- Timing differences (invoiced date vs paid date vs processed date)
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/channel-mapping-tab.mdx b/help-center/raw-data-source-overviews/configuration-sheet/channel-mapping-tab.mdx
index e69de29..2fc7706 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/channel-mapping-tab.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/channel-mapping-tab.mdx
@@ -0,0 +1,19 @@
+---
+title: "Configuration sheet: Channel Mapping tab"
+description: "What the Channel Mapping tab does and how it affects channel, subchannel, and attribution reporting"
+sidebarTitle: "Channel mapping tab"
+icon: "table"
+---
+
+The Channel Mapping tab in the SourceMedium Configuration Sheet is where you define how orders and marketing activity should be routed into consistent **channels** and **subchannels**.
+
+## What this tab impacts
+
+- Channel-level reporting in dashboards
+- Reconciling across platforms (e.g., Shopify vs dashboard) when filtering by channel
+- Segmentation for new vs repeat customers and product performance
+
+## Recommended starting point
+
+- [How does channel mapping work?](/data-inputs/configuration-sheet/how_does_channel_mapping_work)
+- [How can I create order channels and subchannels?](/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels)
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/configuration-sheet-overview.mdx b/help-center/raw-data-source-overviews/configuration-sheet/configuration-sheet-overview.mdx
index e69de29..b3b21d0 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/configuration-sheet-overview.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/configuration-sheet-overview.mdx
@@ -0,0 +1,20 @@
+---
+title: "Configuration Sheet Raw Data Overview"
+description: "How the SourceMedium Configuration Sheet is used for channel mapping, costs, targets, and non-integrated sales inputs"
+sidebarTitle: "Overview"
+icon: "table"
+---
+
+The SourceMedium Configuration Sheet is a set of structured inputs you can use to enrich and standardize reporting across channels.
+
+## What you can do with the configuration sheet
+
+- Define channels and subchannels (channel mapping)
+- Add costs (marketing spend, COGS components, operating expenses)
+- Set targets for scorecards and KPI tracking
+- Upload or supplement non-integrated sales data
+
+## Start here
+
+- [Configuration sheet overview](/data-inputs/configuration-sheet/config-sheet-overview)
+- [Configuration sheet schema](/help-center/raw-data-source-overviews/configuration-sheet/schema)
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs.mdx b/help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs.mdx
index e69de29..5907174 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/costs/fulfillment-costs.mdx
@@ -0,0 +1,65 @@
+---
+title: "Fulfillment Costs"
+description: "How fulfillment and 3PL costs entered in the Configuration Sheet affect profitability reporting"
+sidebarTitle: "Fulfillment costs"
+icon: "warehouse"
+---
+
+Fulfillment costs cover the fees charged by 3PLs, fulfillment centers, and warehouses to pick, pack, and ship your orders.
+
+## What Are Fulfillment Costs?
+
+Fulfillment costs include:
+- **Pick and pack fees**: Per-order handling charges
+- **Storage fees**: Monthly warehouse storage
+- **3PL fees**: ShipBob, Deliverr, Amazon FBA, etc.
+- **Packaging materials**: Boxes, tape, inserts
+
+
+Fulfillment costs are separate from shipping costs (carrier fees). Both contribute to your total cost to fulfill an order.
+
+
+## Where Fulfillment Costs Appear
+
+| Module | Usage |
+|--------|-------|
+| Executive Summary | Part of COGS / gross profit |
+| Orders Deep Dive | Order-level profitability |
+| Contribution Margin | Full order cost analysis |
+
+## Setting Up Fulfillment Costs
+
+
+
+ Review 3PL invoices to determine average fulfillment cost per order
+
+
+ Navigate to the fulfillment costs section
+
+
+ Use flat rate per order or percentage of order value
+
+
+
+## Common Approaches
+
+| Approach | When to Use |
+|----------|-------------|
+| **Flat rate per order** | Single 3PL with predictable fees |
+| **Flat rate per item** | When costs scale with order size |
+| **Percentage of revenue** | When 3PL charges % of GMV |
+
+
+Start with your average cost per order from the last 3 months. You can refine as you get more data.
+
+
+## Related Resources
+
+
+
+ Step-by-step setup guide
+
+
+ Track carrier and delivery costs
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/costs/marketing-costs.mdx b/help-center/raw-data-source-overviews/configuration-sheet/costs/marketing-costs.mdx
index e69de29..b1d831b 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/costs/marketing-costs.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/costs/marketing-costs.mdx
@@ -0,0 +1,83 @@
+---
+title: "Marketing Costs"
+description: "How to enter marketing spend via the Configuration Sheet and how it impacts blended metrics like CPA and ROAS"
+sidebarTitle: "Marketing costs"
+icon: "bullhorn"
+---
+
+Marketing costs entered via the Configuration Sheet ensure your reporting includes **complete spend**—including sources that aren't directly integrated with SourceMedium.
+
+## Why Add Marketing Costs Manually?
+
+SourceMedium integrates with major ad platforms (Meta, Google, TikTok, etc.), but some spend sources require manual entry:
+
+| Source Type | Examples |
+|-------------|----------|
+| **Influencer spend** | Creator payments, gifting costs |
+| **Podcast ads** | Sponsorships, host-read ads |
+| **Affiliate payouts** | Commission payments |
+| **Traditional media** | TV, radio, print |
+| **Offline marketing** | Events, direct mail |
+
+
+If you have significant untracked spend, your blended ROAS and CPA metrics will be inflated. Adding all spend gives you accurate efficiency metrics.
+
+
+## Where Marketing Costs Appear
+
+| Module | Impact |
+|--------|--------|
+| Executive Summary | Blended ROAS, total spend |
+| Marketing Overview | Channel-level spend breakdown |
+| CPA metrics | Cost per acquisition accuracy |
+
+## Setting Up Marketing Costs
+
+
+
+ List all marketing spend not captured by integrations
+
+
+ Navigate to the marketing costs tab
+
+
+ Add spend by date, channel, and optionally subchannel
+
+
+
+## Data Format
+
+Enter marketing costs with these fields:
+
+| Field | Required | Example |
+|-------|----------|---------|
+| Date | Yes | `2026-01-15` |
+| Channel | Yes | `Influencer` |
+| Subchannel | No | `TikTok Creators` |
+| Spend | Yes | `5000` |
+| Notes | No | `January creator campaign` |
+
+## Common Use Cases
+
+
+
+ Track creator payments to understand true influencer CAC and ROAS.
+
+
+ Add podcast spend with promo codes to measure attribution.
+
+
+ Include payouts to calculate true affiliate channel efficiency.
+
+
+
+## Related Resources
+
+
+
+ Step-by-step setup guide
+
+
+ Influencer tracking best practices
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees.mdx b/help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees.mdx
index e69de29..7396e1a 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/costs/merchant-processing-fees.mdx
@@ -0,0 +1,66 @@
+---
+title: "Merchant Processing Fees"
+description: "How merchant processing fees entered in the Configuration Sheet flow into profitability and gross profit reporting"
+sidebarTitle: "Merchant fees"
+icon: "credit-card"
+---
+
+Merchant processing fees are the costs charged by payment providers (Stripe, PayPal, Shopify Payments) to process customer payments.
+
+## What Are Merchant Processing Fees?
+
+These fees typically include:
+- **Transaction fees**: Percentage of transaction (e.g., 2.9%)
+- **Fixed fees**: Per-transaction fee (e.g., $0.30)
+- **Gateway fees**: Monthly/per-transaction gateway costs
+- **Chargeback fees**: Fees for disputed transactions
+
+
+Processing fees vary by payment method. Credit cards typically cost more than ACH/bank transfers.
+
+
+## Where Processing Fees Appear
+
+| Module | Usage |
+|--------|-------|
+| Executive Summary | Contribution margin calculation |
+| Orders Deep Dive | Order-level profitability |
+| P&L Reports | Operating cost line item |
+
+## Common Fee Structures
+
+| Provider | Typical Rate |
+|----------|-------------|
+| Shopify Payments | 2.4-2.9% + $0.30 |
+| Stripe | 2.9% + $0.30 |
+| PayPal | 2.9% + $0.49 |
+| Shop Pay | 2.4-2.6% + $0.30 |
+
+## Setting Up Processing Fees
+
+
+
+ Review payment provider statements to find your average rate across all payment methods
+
+
+ Navigate to the merchant processing section
+
+
+ Enter your blended rate (e.g., 2.7% for most DTC brands)
+
+
+
+
+Use your **blended rate** across all payment types. Most brands see 2.5-3.0% when combining credit cards, PayPal, and alternative payments.
+
+
+## Related Resources
+
+
+
+ Step-by-step setup guide
+
+
+ How processing fees affect contribution margin
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs.mdx b/help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs.mdx
index e69de29..3a9d7aa 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/costs/product-costs.mdx
@@ -0,0 +1,73 @@
+---
+title: "Product Costs (COGS)"
+description: "How product costs are sourced, where they appear in dashboards, and how to fill gaps using the Configuration Sheet"
+sidebarTitle: "Product costs"
+icon: "box"
+---
+
+Product costs (COGS) power profitability metrics like gross profit and contribution margin across your SourceMedium dashboards.
+
+## How Product Costs Work
+
+SourceMedium pulls product costs from Shopify's `Cost per item` field at the variant level. This enables:
+- **Order-level profitability**: Gross profit per order
+- **Customer-level LTV**: Profit-based lifetime value
+- **Product-level margins**: Gross margin by product/collection
+
+
+SourceMedium tracks cost changes over time. Orders use the product cost that was active when the order was placed.
+
+
+## Where Costs Appear
+
+| Module | Cost Usage |
+|--------|------------|
+| Executive Summary | Gross profit, contribution margin |
+| LTV & Retention | Profit-adjusted LTV |
+| Product Performance | Product-level margins |
+| Orders Deep Dive | Order-level profitability |
+
+## Setting Up Product Costs
+
+
+
+ Go to **Products** → select product → select variant → enter **Cost per item**
+
+
+ Include product cost + inbound shipping/duties for accurate margins
+
+
+ Let your team know costs are ready so we can enable the feature
+
+
+
+## Common Scenarios
+
+
+
+ Set up costs from Shopify product data
+
+
+ Backfill costs for older orders
+
+
+ Override Shopify costs with custom values
+
+
+ Add costs for non-Shopify products
+
+
+
+## FAQs
+
+
+
+ Use **landed cost**: product cost + inbound shipping + duties/tariffs. This gives the most accurate gross margin.
+
+
+ Update the cost in Shopify when it changes. SourceMedium tracks historical costs—old orders keep old costs, new orders use new costs.
+
+
+ Cost changes typically reflect in dashboards within 24 hours after the next data sync.
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/costs/shipping-costs.mdx b/help-center/raw-data-source-overviews/configuration-sheet/costs/shipping-costs.mdx
index e69de29..aa0c56c 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/costs/shipping-costs.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/costs/shipping-costs.mdx
@@ -0,0 +1,60 @@
+---
+title: "Shipping Costs"
+description: "How shipping costs entered in the Configuration Sheet flow into profitability and gross profit reporting"
+sidebarTitle: "Shipping costs"
+icon: "truck"
+---
+
+Shipping costs represent the cost you pay to deliver orders to customers. Adding shipping costs enables accurate gross profit and contribution margin calculations.
+
+## How Shipping Costs Work
+
+Shipping costs can be entered as:
+- **Flat rate per order**: Same cost for every order
+- **Percentage of shipping revenue**: e.g., 80% of what customer paid
+- **Per-order values**: Custom cost per order via upload
+
+## Where Shipping Costs Appear
+
+| Module | Usage |
+|--------|-------|
+| Executive Summary | Gross profit calculation |
+| Orders Deep Dive | Order-level profitability |
+| LTV & Retention | Profit-adjusted LTV metrics |
+
+## Setting Up Shipping Costs
+
+
+
+ Open your Configuration Sheet from SourceMedium settings
+
+
+ Find the shipping costs section
+
+
+ Choose flat rate, percentage, or upload order-level costs
+
+
+
+## Common Approaches
+
+| Approach | Best For | Example |
+|----------|----------|---------|
+| **Flat rate** | Simple, consistent shipping | $5.00 per order |
+| **Percentage** | Variable shipping costs | 75% of shipping charged |
+| **Per-order upload** | Complex/negotiated rates | CSV with order-specific costs |
+
+
+If you use multiple carriers with different rates, consider using the average cost across all orders. You can refine later with per-order data.
+
+
+## Related Resources
+
+
+
+ Step-by-step setup guide
+
+
+ Track 3PL and fulfillment fees
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/sales-tab.mdx b/help-center/raw-data-source-overviews/configuration-sheet/sales-tab.mdx
index e69de29..f8e306d 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/sales-tab.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/sales-tab.mdx
@@ -0,0 +1,12 @@
+---
+title: "Configuration sheet: Sales tab"
+description: "How to enter non-integrated sales data and when to use the Sales tab in the Configuration Sheet"
+sidebarTitle: "Sales tab"
+icon: "table"
+---
+
+Use the Sales tab to enter sales data for channels that are not directly integrated, or to supplement gaps in your sales feeds.
+
+## Start here
+
+- [How do I enter non-integrated sales data (Sales tab)?](/data-inputs/configuration-sheet/how-do-i-enter-non-integrated-sales-data-sales-tab)
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/schema.mdx b/help-center/raw-data-source-overviews/configuration-sheet/schema.mdx
new file mode 100644
index 0000000..968e558
--- /dev/null
+++ b/help-center/raw-data-source-overviews/configuration-sheet/schema.mdx
@@ -0,0 +1,224 @@
+---
+title: "Configuration sheet: schema"
+description: "Exact column schema for each Configuration Sheet tab and how SourceMedium ingests dates and ranges."
+sidebarTitle: "Schema"
+icon: "table"
+---
+
+This page is a **reference spec** for the SourceMedium Configuration Sheet: what columns exist on each tab, which fields are required, and how dates/ranges are interpreted during ingestion.
+
+
+Your Configuration Sheet is shared during onboarding (email + Slack) and is typically synced into SourceMedium within 24 hours.
+
+
+---
+
+## General rules
+
+### Date formats
+
+Different tabs parse dates differently:
+
+- **Targets / Sales / Cost (Marketing Costs)**: dates are parsed from common string formats, including:
+ - `YYYY-MM-DD`
+ - `MM-DD-YYYY`
+ - `MM/DD/YYYY`
+ - `MM/DD/YY`
+- **Financial Cost tabs**: `date_start` / `date_end` are parsed as `MM/DD/YYYY` specifically.
+
+### Date ranges
+
+- Where a tab supports a date range, `date_end` is treated as **inclusive** (the range includes both `date_start` and `date_end`).
+- For tabs that amortize/spread amounts, the spread is done evenly across the number of days in the inclusive range.
+
+---
+
+## Targets tab
+
+Use the Targets tab for KPI targets displayed in scorecards and executive reporting.
+
+
+Targets are treated as **daily values** across the selected date range. If you want a monthly total target, enter the per-day target value.
+
+
+
+If multiple Target rows overlap on the same day for the same channel:
+- Summable metrics (e.g., revenue, orders, spend, sessions) are **summed**
+- Ratio-like metrics (e.g., AOV, CPA, ROAS) use the **max** value for that day
+
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `channel` | STRING | Yes | Targets are keyed by channel. |
+| `date_start` | STRING | Yes | Parsed into a date. |
+| `date_end` | STRING | No | If provided, targets apply to each day in the inclusive range. |
+| `gross_revenue` | FLOAT64 | No | Target value (per day if using a range). |
+| `net_revenue` | FLOAT64 | No | Target value (per day if using a range). |
+| `total_revenue` | FLOAT64 | No | Target value (per day if using a range). |
+| `orders` | FLOAT64 | No | Target value (per day if using a range). |
+| `spend` | FLOAT64 | No | Target value (per day if using a range). |
+| `sessions` | FLOAT64 | No | Target value (per day if using a range). |
+| `aov` | FLOAT64 | No | Ratio/derived KPI targets are applied as a constant value across the range. |
+| `cpa` | FLOAT64 | No | Ratio/derived KPI targets are applied as a constant value across the range. |
+| `cpo` | FLOAT64 | No | Ratio/derived KPI targets are applied as a constant value across the range. |
+| `conversion_rate` | FLOAT64 | No | Ratio/derived KPI targets are applied as a constant value across the range. |
+| `roas` | FLOAT64 | No | Ratio/derived KPI targets are applied as a constant value across the range. |
+| `primary_product_units` | NUMERIC | No | Optional (brand-dependent). |
+
+---
+
+## Channel Mapping tab
+
+Use Channel Mapping to route orders (and some marketing records) into consistent **channels**, **subchannels**, and **vendors** using rule-based matching.
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `row` | INT64 | Yes | Rule priority. Higher values are evaluated first. `0` disables a row. |
+| `attribute` | STRING | Yes | Which input field to match against. |
+| `operator` | STRING | Yes | One of: `equals`, `contains`, `in` (must match exactly). |
+| `value` | STRING | Yes | Match value (comparison is case-insensitive). For `in`, use a comma-separated list (whitespace is ignored). |
+| `channel` | STRING | No | Optional output channel when matched. |
+| `sub_channel` | STRING | No | Optional output subchannel when matched. |
+| `vendor` | STRING | No | Optional output vendor when matched. |
+| `cost_per_order` | FLOAT64 | No | Optional CPO value associated with the matched rule. |
+
+
+Rules are evaluated from highest to lowest derived **weight**. In addition to `row`, some non-default channels are intentionally boosted to win over lower-priority “online” rules.
+
+
+### Supported `attribute` values
+
+These attributes are supported by the channel mapping ingestion logic:
+
+- `source` (UTM source)
+- `medium` (UTM medium)
+- `source_medium` (combined UTM source/medium)
+- `campaign` (UTM campaign)
+- `discount_codes` (order discount codes)
+- `order_tags` (order tags)
+- `skus` (product SKUs)
+- `shopify_sales_channel` (Shopify sales channel / marketplace signal)
+
+---
+
+## Sales tab
+
+Use the Sales tab to enter **non-integrated sales** and have them included in reporting.
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `channel` | STRING | Yes | Sales channel bucket for the entry. |
+| `sub_channel` | STRING | No | Optional label for internal organization. |
+| `date_start` | STRING | Yes | Parsed into a date. |
+| `date_end` | STRING | No | If provided, amounts are spread evenly across the inclusive range. |
+| `gross_revenue` | FLOAT64 | No | Total for the period (spread evenly if `date_end` provided). |
+| `net_revenue` | FLOAT64 | No | Total for the period (spread evenly if `date_end` provided). |
+| `orders` | FLOAT64 | No | Total for the period (spread evenly if `date_end` provided). |
+| `primary_product_units` | NUMERIC | No | Optional (brand-dependent). |
+| `discounts` | FLOAT64 | No | Total for the period (spread evenly if `date_end` provided). |
+| `refunds` | FLOAT64 | No | Total for the period (spread evenly if `date_end` provided). |
+
+
+Orders are stored as whole numbers; when a Sales row spans multiple days, order counts are distributed across the range to stay integer-valued.
+
+
+---
+
+## Cost tab (Marketing Costs)
+
+Use the Cost tab (sometimes labeled **Marketing Costs**) for marketing spend that isn’t captured by an integration.
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Used to categorize spend (commonly `Marketing`). |
+| `channel` | STRING | Yes | Channel where you want reporting to reflect spend. |
+| `sub_channel` | STRING | No | Optional subchannel. |
+| `vendor` | STRING | No | Optional platform/vendor. |
+| `cost` | FLOAT64 | Yes | Total cost for the period. |
+| `date_start` | STRING | Yes | Parsed into a date. |
+| `date_end` | STRING | No | If provided, cost is spread evenly across the inclusive range. |
+
+---
+
+## Financial Cost tabs
+
+Financial Cost tabs define rates used for profit and cost reporting. These tabs require `date_start` and `date_end` and parse dates as **`MM/DD/YYYY`**.
+
+
+For Financial Cost tabs, rows without a `date_end` are ignored.
+
+
+### Financial Cost - Product COGS
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Typically `Financial`. |
+| `channel` | STRING | Yes | Channel the cost applies to. |
+| `expense_channel` | STRING | Yes | Typically `Product COGS`. |
+| `sku` | STRING | Yes | SKU/variant identifier the cost applies to. |
+| `fixed_cost` | FLOAT64 | Yes | Per-unit product cost for the SKU. |
+| `date_start` | STRING | Yes | `MM/DD/YYYY` |
+| `date_end` | STRING | Yes | `MM/DD/YYYY` |
+
+### Financial Cost - Shipping
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Typically `Financial`. |
+| `channel` | STRING | Yes | Channel the cost applies to. |
+| `expense_channel` | STRING | Yes | Typically `Shipping Cost`. |
+| `region` | STRING | Yes | Region bucket used for allocation. |
+| `cost` | FLOAT64 | Yes | Per-order shipping cost for the period. |
+| `date_start` | STRING | Yes | `MM/DD/YYYY` |
+| `date_end` | STRING | Yes | `MM/DD/YYYY` |
+
+### Financial Cost - Fulfillment
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Typically `Financial`. |
+| `channel` | STRING | Yes | Channel the cost applies to. |
+| `expense_channel` | STRING | Yes | Typically `Fulfillment Cost`. |
+| `region` | STRING | Yes | Region bucket used for allocation. |
+| `cost` | FLOAT64 | Yes | Per-order fulfillment cost for the period. |
+| `date_start` | STRING | Yes | `MM/DD/YYYY` |
+| `date_end` | STRING | Yes | `MM/DD/YYYY` |
+
+### Financial Cost - Merchant Processing Fees
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Typically `Financial`. |
+| `channel` | STRING | Yes | Channel the cost applies to. |
+| `expense_channel` | STRING | Yes | Typically `Merchant Processing Fees`. |
+| `region` | STRING | Yes | Region bucket used for allocation. |
+| `vendor` | STRING | Yes | Payment processor/platform label. |
+| `fixed_cost` | FLOAT64 | Yes | Fixed per-order fee. |
+| `variable_cost` | FLOAT64 | Yes | Variable rate (used as a rate downstream). |
+| `date_start` | STRING | Yes | `MM/DD/YYYY` |
+| `date_end` | STRING | Yes | `MM/DD/YYYY` |
+
+### Financial Cost - Operating Expenses
+
+| Column | Type | Required | Notes |
+|--------|------|----------|------|
+| `category` | STRING | Yes | Typically `Financial`. |
+| `channel` | STRING | Yes | Channel the cost applies to. |
+| `expense_channel` | STRING | Yes | Typically `Operating Expenses`. |
+| `region` | STRING | Yes | Region bucket used for allocation. |
+| `cost` | FLOAT64 | Yes | Total operating expenses amount for the period. |
+| `date_start` | STRING | Yes | `MM/DD/YYYY` |
+| `date_end` | STRING | Yes | `MM/DD/YYYY` |
+
+---
+
+## Related resources
+
+
+
+ Start here for how-to guides and workflows.
+
+
+ Learn the routing/precedence logic behind channel mapping.
+
+
diff --git a/help-center/raw-data-source-overviews/configuration-sheet/targets-tab.mdx b/help-center/raw-data-source-overviews/configuration-sheet/targets-tab.mdx
index e69de29..4593881 100644
--- a/help-center/raw-data-source-overviews/configuration-sheet/targets-tab.mdx
+++ b/help-center/raw-data-source-overviews/configuration-sheet/targets-tab.mdx
@@ -0,0 +1,12 @@
+---
+title: "Configuration sheet: Targets tab"
+description: "How targets work in SourceMedium and how to set KPI targets for dashboards and scorecards"
+sidebarTitle: "Targets tab"
+icon: "table"
+---
+
+Use the Targets tab to define KPI targets (e.g., revenue, CPA, ROAS) used for scorecards and goal tracking.
+
+## Start here
+
+- [Can I set targets in my dashboard?](/data-inputs/configuration-sheet/can-i-set-targets-in-my-dashboard)
diff --git a/help-center/raw-data-source-overviews/google-ads-overview.mdx b/help-center/raw-data-source-overviews/google-ads-overview.mdx
index 2c3843f..50eed46 100644
--- a/help-center/raw-data-source-overviews/google-ads-overview.mdx
+++ b/help-center/raw-data-source-overviews/google-ads-overview.mdx
@@ -1,7 +1,17 @@
---
title: 'Google Ads'
-description: ''
+description: "What SourceMedium ingests from Google Ads and what to check when reconciling spend and performance"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium integrates Google Ads to support paid media reporting and blended marketing performance.
+
+## Setup
+
+- [Google Ads integration instructions](/data-inputs/platform-integration-instructions/google-ads-integration)
+
+## What to validate
+
+- Spend alignment (currency, date range, and timezone)
+- Attribution window differences between Google Ads vs your dashboards
+- Campaign naming conventions and UTM mapping consistency
diff --git a/help-center/raw-data-source-overviews/hubspot-overview.mdx b/help-center/raw-data-source-overviews/hubspot-overview.mdx
index 62dfc6a..f54ed5a 100644
--- a/help-center/raw-data-source-overviews/hubspot-overview.mdx
+++ b/help-center/raw-data-source-overviews/hubspot-overview.mdx
@@ -1,7 +1,16 @@
---
title: 'HubSpot'
-description: ''
+description: "What SourceMedium ingests from HubSpot and where HubSpot data typically shows up in reporting"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium can ingest HubSpot data to support lifecycle, CRM, and marketing operations analysis.
+
+## Setup
+
+- [HubSpot integration instructions](/data-inputs/platform-integration-instructions/hubspot-integration)
+
+## What to validate
+
+- Contact identifiers and email matching behavior
+- Timestamp consistency (created vs updated vs event time)
diff --git a/help-center/raw-data-source-overviews/klaviyo-overview.mdx b/help-center/raw-data-source-overviews/klaviyo-overview.mdx
index 26f3b55..d9ce2af 100644
--- a/help-center/raw-data-source-overviews/klaviyo-overview.mdx
+++ b/help-center/raw-data-source-overviews/klaviyo-overview.mdx
@@ -1,7 +1,18 @@
---
title: 'Klaviyo'
-description: ''
+description: "What SourceMedium ingests from Klaviyo and common nuances when validating email/SMS performance"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium integrates Klaviyo to support email and SMS performance analysis.
+
+## Setup
+
+- [Klaviyo integration instructions](/data-inputs/platform-integration-instructions/klaviyo-integration)
+
+## Common caveats
+
+- Email/SMS attribution depends heavily on consistent UTM tagging.
+- Platform-reported conversions can differ from warehouse-reconciled revenue due to attribution windows and deduplication.
+
+See: [Klaviyo: Data nuances & limitations](/data-inputs/platform-supporting-resources/klaviyo/klaviyo-data-nuances-and-limitations)
diff --git a/help-center/raw-data-source-overviews/mailchimp-overview.mdx b/help-center/raw-data-source-overviews/mailchimp-overview.mdx
deleted file mode 100644
index 36370b0..0000000
--- a/help-center/raw-data-source-overviews/mailchimp-overview.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 'Mailchimp'
-description: ''
-icon: 'plug'
----
-
-blah blah blah
\ No newline at end of file
diff --git a/help-center/raw-data-source-overviews/meta-ads-overview.mdx b/help-center/raw-data-source-overviews/meta-ads-overview.mdx
index d862df2..f2fdc68 100644
--- a/help-center/raw-data-source-overviews/meta-ads-overview.mdx
+++ b/help-center/raw-data-source-overviews/meta-ads-overview.mdx
@@ -1,7 +1,17 @@
---
title: 'Meta Ads'
-description: ''
+description: "What SourceMedium ingests from Meta Ads and what to check when reconciling spend and ROAS"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium integrates Meta Ads (Facebook) to support paid social reporting across campaigns, ad sets, and creatives.
+
+## Setup
+
+- [Meta Ads integration instructions](/data-inputs/platform-integration-instructions/meta-integration)
+
+## What to validate
+
+- Spend alignment (currency, timezone, and date range)
+- Attribution window differences between Meta and other tools
+- Consistent campaign/ad naming for reporting rollups
diff --git a/help-center/raw-data-source-overviews/stripe-overview.mdx b/help-center/raw-data-source-overviews/stripe-overview.mdx
index b76321c..a43eef8 100644
--- a/help-center/raw-data-source-overviews/stripe-overview.mdx
+++ b/help-center/raw-data-source-overviews/stripe-overview.mdx
@@ -1,7 +1,18 @@
---
title: 'Stripe'
-description: ''
+description: "What SourceMedium ingests from Stripe and common reasons Stripe revenue differs from order-based reporting"
icon: 'plug'
---
-blah blah blah
\ No newline at end of file
+SourceMedium can ingest Stripe to support payment-level and subscription revenue analysis.
+
+## Setup
+
+- [Stripe integration instructions](/data-inputs/platform-integration-instructions/stripe-integration)
+
+## Common caveats
+
+- Stripe is payment-centric; ecommerce reporting is typically order-centric. Align on the question before validating.
+- Metadata mapping can affect how transactions are categorized.
+
+See: [How does Stripe metadata work?](/help-center/faq/data-faqs/how-does-stripe-metadata-work)
diff --git a/help-center/slack-bot-setup.mdx b/help-center/slack-bot-setup.mdx
new file mode 100644
index 0000000..226b121
--- /dev/null
+++ b/help-center/slack-bot-setup.mdx
@@ -0,0 +1,23 @@
+---
+title: "Slack bot setup"
+description: "How to get the SourceMedium Slack bot installed and what information you need to provide"
+icon: "message"
+---
+
+SourceMedium can deliver a daily metrics snapshot to Slack. Your SourceMedium team can help install and configure the bot for your account.
+
+## What you’ll need
+
+- Your preferred Slack channel (or a new shared channel with SourceMedium)
+- Confirmation of which Shopify store(s) and brand(s) the report should cover
+- The metric list you want to see (up to plan limits)
+
+## Setup steps (high level)
+
+1. Request Slack bot installation from your SourceMedium team in Slack or by emailing `support@sourcemedium.com`.
+2. Confirm the channel where the bot should post.
+3. Confirm which metrics you want included.
+
+## Metric options
+
+See: [What metrics can I include in my daily Slack Bot report?](/help-center/faq/account-management-faqs/what-metrics-can-i-include-in-my-daily-slack-bot-report)
diff --git a/help-center/template-gallery.mdx b/help-center/template-gallery.mdx
new file mode 100644
index 0000000..050665a
--- /dev/null
+++ b/help-center/template-gallery.mdx
@@ -0,0 +1,25 @@
+---
+title: "Template gallery"
+description: "What the SourceMedium template gallery is, how to use it for inspiration, and how to copy templates"
+icon: "layout"
+---
+
+The SourceMedium template gallery is a collection of report modules and dashboards that can be used as starting points for analysis and customization.
+
+## What you’ll find
+
+- Example visualizations for common questions (marketing, product performance, retention, profitability)
+- Patterns for filters, breakdowns, and scorecards
+- Optional modules you can request or replicate
+
+## How to use templates
+
+1. Identify a template that matches your question.
+2. Copy the template into your Looker Studio environment.
+3. Map the underlying data sources to your SourceMedium tables.
+
+Start here:
+
+- [Looker Studio template copy instructions](/data-activation/template-resources/looker-studio-template-copy-instructions)
+- [Looker Studio report template directory](/data-activation/template-resources/sm-looker-report-template-directory)
+- [SQL Query Library](/data-activation/template-resources/sql-query-library) — Copy-paste SQL templates for BigQuery
diff --git a/help-center/what-is-sourcemedium.mdx b/help-center/what-is-sourcemedium.mdx
index 6eae918..fc5dc82 100644
--- a/help-center/what-is-sourcemedium.mdx
+++ b/help-center/what-is-sourcemedium.mdx
@@ -1,22 +1,22 @@
---
title: "What Is SourceMedium"
+description: "Overview of SourceMedium and how to use this Help Center to find onboarding, integrations, configuration tutorials, and support."
icon: 'map'
---
-
SourceMedium is a
vertical data infrastructure solution
that abstracts away the business and technical complexity of moving, cleaning,
standardizing, and preparing data so you can focus on developing actionable insights that help you differentiate your company.
-We work with hundreds of merchants to identify their most critical analytical use cases for their businesses and develop
-data ingestion and transformation processes that streamline the journey from raw data to business decision.
+We work with e-commerce teams to identify their most critical analytical use cases and build data ingestion and transformation
+processes that streamline the journey from raw data to business decisions.
To learn more about how we do this, see [Data Transformation](/data-transformations/philosophy) and [Data Activation](/data-activation/managed-data-warehouse/overview).
- **This help center is currently under construction.**
-
- All information presented is accurate and up to date, but stay tuned for more to come!
+ We’re actively expanding this Help Center. If you can’t find what you need, contact your SourceMedium team and tell us what you were trying to accomplish.
+
+ If anything looks outdated or unclear, tell us — we’ll prioritize fixing it.
@@ -26,7 +26,7 @@ To learn more about how we do this, see [Data Transformation](/data-transformati
-
+
@@ -34,4 +34,4 @@ To learn more about how we do this, see [Data Transformation](/data-transformati
-If you aren't finding what you need on this site, you can always reach out to the Customer Solutions team via Slack or by email at support@sourcemedium.com!
\ No newline at end of file
+If you aren't finding what you need on this site, you can always reach out to the Customer Solutions team via Slack or by email at support@sourcemedium.com!
diff --git a/images/article-imgs/applovin-integration/acct_tab.png b/images/article-imgs/applovin-integration/acct_tab.png
deleted file mode 100644
index 65722ac..0000000
Binary files a/images/article-imgs/applovin-integration/acct_tab.png and /dev/null differ
diff --git a/images/article-imgs/applovin-integration/keys.png b/images/article-imgs/applovin-integration/keys.png
deleted file mode 100644
index e6ad203..0000000
Binary files a/images/article-imgs/applovin-integration/keys.png and /dev/null differ
diff --git a/images/article-imgs/applovin-integration/keys_highlight.png b/images/article-imgs/applovin-integration/keys_highlight.png
new file mode 100644
index 0000000..7a2dee9
Binary files /dev/null and b/images/article-imgs/applovin-integration/keys_highlight.png differ
diff --git a/images/article-imgs/applovin-integration/report_key.png b/images/article-imgs/applovin-integration/report_key.png
deleted file mode 100644
index 49ffccd..0000000
Binary files a/images/article-imgs/applovin-integration/report_key.png and /dev/null differ
diff --git a/images/article-imgs/applovin-integration/reporting_key.png b/images/article-imgs/applovin-integration/reporting_key.png
new file mode 100644
index 0000000..267e25c
Binary files /dev/null and b/images/article-imgs/applovin-integration/reporting_key.png differ
diff --git a/images/article-imgs/applovin-integration/tab.png b/images/article-imgs/applovin-integration/tab.png
new file mode 100644
index 0000000..8db07b3
Binary files /dev/null and b/images/article-imgs/applovin-integration/tab.png differ
diff --git a/images/article-imgs/ga-universal-integration/image_(37).png b/images/article-imgs/ga-universal-integration/image-37.png
similarity index 100%
rename from images/article-imgs/ga-universal-integration/image_(37).png
rename to images/article-imgs/ga-universal-integration/image-37.png
diff --git a/images/article-imgs/ga-universal-integration/image_(38).png b/images/article-imgs/ga-universal-integration/image-38.png
similarity index 100%
rename from images/article-imgs/ga-universal-integration/image_(38).png
rename to images/article-imgs/ga-universal-integration/image-38.png
diff --git a/images/article-imgs/recharge-integration/Untitled4.png b/images/article-imgs/recharge-integration/Untitled4.png
deleted file mode 100644
index 605ded4..0000000
Binary files a/images/article-imgs/recharge-integration/Untitled4.png and /dev/null differ
diff --git a/images/article-imgs/recharge-integration/Untitled42.png b/images/article-imgs/recharge-integration/Untitled42.png
new file mode 100644
index 0000000..d105ed6
Binary files /dev/null and b/images/article-imgs/recharge-integration/Untitled42.png differ
diff --git a/images/platform-logos/mailchimp-square-logo.svg b/images/platform-logos/mailchimp-square-logo.svg
deleted file mode 100644
index 0ca18a5..0000000
--- a/images/platform-logos/mailchimp-square-logo.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/index.mdx b/index.mdx
new file mode 100644
index 0000000..225a00e
--- /dev/null
+++ b/index.mdx
@@ -0,0 +1,142 @@
+---
+title: "SourceMedium Docs"
+description: "Start here for onboarding, integrations, configuration sheet, dashboards, table schemas, and support."
+sidebarTitle: "Home"
+icon: "house"
+---
+
+Your starting point for SourceMedium documentation. Organized around how teams actually work: get set up, connect data, understand definitions, and use dashboards and warehouse outputs confidently.
+
+---
+
+## Start here
+
+
+
+ Quick orientation and pointers to the most-used sections.
+
+
+ Implementation steps and what to validate early.
+
+
+ How SourceMedium ingests, standardizes, and publishes outputs.
+
+
+ Support channels, request patterns, and what to include in questions.
+
+
+
+---
+
+## AI Analyst
+
+
+
+ Ask questions about your data in plain English. Get answers with charts and SQL — all within Slack.
+
+
+ See what you can ask across orders, customers, marketing, and more.
+
+
+
+---
+
+## Choose your path
+
+
+
+ Dashboards, executive metrics, and common analysis entry points.
+
+
+ Attribution context, reconciliation, and tracking quality.
+
+
+ Table schemas, naming conventions, and warehouse-ready outputs.
+
+
+
+---
+
+## Understand your data
+
+
+
+ Check if your data is fresh, available, and ready for analysis.
+
+
+ Diagnose and improve tracking coverage for marketing attribution.
+
+
+ Tag links correctly for reliable last-click attribution.
+
+
+ How SourceMedium selects the winning source when multiple exist.
+
+
+
+---
+
+## Core sections
+
+
+
+ Supported integrations, setup guides, and what to do when an integration isn't available.
+
+
+ Targets, channel mapping, marketing costs, and non-integrated sales.
+
+
+ How SourceMedium cleans and enriches data before activation.
+
+
+ Sales channel and order type classification for reporting.
+
+
+
+---
+
+## Reference
+
+
+
+ Metric definitions and formulas.
+
+
+ Dimension definitions and how to interpret them.
+
+
+ Warehouse table documentation for `sm_transformed_v2`.
+
+
+ Copy-paste SQL templates for common analyses in BigQuery.
+
+
+
+---
+
+## Help & support
+
+
+
+ Common questions across dashboards, data, and account management.
+
+
+ Canonical terms and definitions.
+
+
+ Reach us via Slack or support@sourcemedium.com.
+
+
+
+---
+
+## Advanced
+
+
+
+ MTA concepts and how to interpret outputs.
+
+
+ Common questions and interpretation guidance.
+
+
diff --git a/internal/documentation-best-practices.mdx b/internal/documentation-best-practices.mdx
deleted file mode 100644
index 5861189..0000000
--- a/internal/documentation-best-practices.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Documentation Best Practices'
-description: 'Best practices for writing and maintaining markdown documentation using Mintlify'
-icon: 'star'
----
\ No newline at end of file
diff --git a/internal/exec-summ-walk-thru-test.mdx b/internal/exec-summ-walk-thru-test.mdx
deleted file mode 100644
index 2b423e9..0000000
--- a/internal/exec-summ-walk-thru-test.mdx
+++ /dev/null
@@ -1,46 +0,0 @@
-# Executive Summary
-
-Created by: Kathleen Guzic
-Status: Backlog
-Date added: December 13, 2023 9:01 AM
-Last Edited: December 13, 2023 12:37 PM
-
-INSERT EXEC DASH WALKTHRU VIDEO
-
-SCRIPT:
-
-Your executive summary is a high level, blended view of all your integrated data. This is where you can view the overall health of your business. For example you can track what the most important key performance indicators are for your business, sales performance, acquisition performance, marketing efficiency and new vs. repeat customers.
-There are over 100 metrics to choose from to view in your Executive Summary. The link at the top of the module will bring you to the full list.
-
-The Executive Summary mimics transaction-based reporting.
-Example: The day on which the refund is made and is recorded like a transaction log, much as you would for accounting purposes
-
-First step is your executive summary module. This module is an overview of the overall health of your brand. This includes all integrated data, sources, marketing and sales and subscriptions, etc. and it’s a blender do you have all of those sources and includes prudent KPIs.
-
-The executive summary works like the Shopify sales report as it is transaction based that means each order and return is logged.
-
-
- - Blended view of all your integrated data sources
- - This is where you will find insights into the overall health of your brand
- - Follows accounting rules and when the correct filters are selected, this will match your Shopify Sales Over Time report
-
-
- - [How is my Online DTC store doing vs. my Amazon store?](https://www.loom.com/share/eed93bc808b6466b8cea32f78c9ff079?sid=feb0ba43-42ba-4580-a14a-0c83f7e50df4)
- - Embedded link:
- - [What is my blended cost per acquisition (CPA)?](https://www.loom.com/share/b6d5ba880e9c4334a4a679a1e9a19187?sid=8809ade0-5595-4c45-91a2-ecda09150938)
- - Embedded link:
- - [What percentage of orders are first time vs. repeat?](https://www.loom.com/share/fd88e320fcf540d7a17f231a8ed766a4?sid=f6764f3d-73ac-4bb3-a44d-2d0e52f18410)
- - Embeddedlink:
-
-
-
- The Executive Summary is designed to mirror the accounting rules present in the Shopify Sales Report, and will almost always match 1:1. However, there are some instances where you won't see a 1:1 match:
-
- 1. If your brand has our `Exclude $0 Orders` feature enabled, you will see a revenue and orders mismatch. This feature excludes orders with a total revenue of $0 from all Executive Summary and Retention dashboard data. If you're unsure if you have this feature enabled, reach out to our Support team in Slack or via email at [help@sourcemedium.com](mailto:help@sourcemedium.com).
-
- [See here for a deeper explanation of this feature](https://help.sourcemedium.com/articles/exclude-0-orders-feature-overview)
-
- 2. If your brand has any data cleaning rules in the Channel Mapping tab your Configuration Sheet-- e.g. any rules routing orders to a channel other than Online DTC -- you will see a mismatch if only Online DTC is selected in the channel dropdown (located at the top right-hand corner of your report, under the date range filter).
-
- If you are running sales through Amazon, be sure to deselect "Amazon" in the channel dropdown when comparing sales data between the Executive Summary and Shopify Sales report.
-
\ No newline at end of file
diff --git a/internal/placeholder-page.mdx b/internal/placeholder-page.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/internal/setup.mdx b/internal/setup.mdx
deleted file mode 100644
index 9f37722..0000000
--- a/internal/setup.mdx
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: "Internal Environment set up and learning"
----
-
-To get started with Mintlify, first you need to have...
-- A GitHub account
- - you can use your personal one, if it already exists
- - if you don't already have an account, [create one](https://github.com/)
-- Git set up on your local machine
- - [1st time Git set up](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)
-- Mintlify packages installed on local machine
- - [Mintlify development set up guide](https://mintlify.com/docs/development)
-
-
-Helpful resources
-- [Git command sheet sheet](https://gist.github.com/cferdinandi/ef665330286fd5d7127d)
-- testing staging
-
diff --git a/internal/styling-scratch-pad.mdx b/internal/styling-scratch-pad.mdx
deleted file mode 100644
index 5c5b274..0000000
--- a/internal/styling-scratch-pad.mdx
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: 'Styling Scratch Pad'
-description: 'An internal page to test out styling as it renders for the user'
-icon: 'star'
----
-
-### `Accordions` & `AccordionGroups`
-#### Accordion
-
-
- Inner content
-
-
-
-### `Snippets` & `Snippets` w/ `Tooltips`
-Using a tooltip as a snippet seems to work fine:
-```markdown
-
-```
-
-
-However, wrapping that snippet in an `` element does not allow tooltip to expand:
-```markdown
-
-```
-
-
-Calling a snippet inline breaks page, issue acknowledged by Mintlify
-```markdown
-Cost per acquisition, or is a representation of how much it costs (in terms of marketing dollars) to acquire a new customer
-```
\ No newline at end of file
diff --git a/mta/mta-advanced-documentation.mdx b/mta/mta-advanced-documentation.mdx
index 873b1cc..914a95b 100644
--- a/mta/mta-advanced-documentation.mdx
+++ b/mta/mta-advanced-documentation.mdx
@@ -1,7 +1,7 @@
---
-title: "Source Medium MTA Advanced Documentation"
+title: "SourceMedium MTA Advanced Documentation"
sidebarTitle: "MTA Advanced Documentation"
-description: "Learn the basics of Source Medium Multi-Touch Attribution"
+description: "Technical deep dive into MTA methodology, attribution windows, and advanced configuration"
icon: "gear"
iconType: "solid"
---
@@ -103,6 +103,79 @@ We assess the complexity of a purchase journey by counting the **distinct** valu
In our default reporting template, you can set a minimum number of distinct values required for a journey to be included in MTA analysis. By default, this is set to **2**.
+### Linear Attribution Deduplication
+
+Linear attribution now implements **session-based deduplication** to ensure marketing effectiveness is measured accurately without over-crediting repetitive interactions.
+
+#### How It Works
+
+1. **User Identification**: Each touchpoint is associated with a user via `event_user_id`
+2. **First Occurrence Tracking**: Within each purchase journey, only the first occurrence of a dimension value receives attribution
+3. **Credit Distribution**: The linear multiplier is calculated based on unique dimension values, not total touches
+
+#### Implementation Details
+
+```sql
+-- Deduplication logic in obt_purchase_journeys_with_mta_models
+SELECT
+ purchase_order_id,
+ source_system,
+ event_user_id,
+ dimension_value.marketing_channel,
+ event_local_datetime,
+ CASE
+ WHEN ROW_NUMBER() OVER (
+ PARTITION BY purchase_order_id, source_system, event_user_id, dimension_value.marketing_channel
+ ORDER BY event_local_datetime
+ ) = 1 THEN TRUE
+ ELSE FALSE
+ END AS is_first_occurrence_marketing_channel
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE sm_store_id = 'your-sm_store_id'
+ AND sm_event_name = 'purchase'
+ AND dimension_value.marketing_channel IS NOT NULL
+LIMIT 10;
+```
+
+#### Multiplier Calculation
+
+```sql
+-- Uses unique dimension value count
+SELECT
+ purchase_order_id,
+ unique_dimension_value_count.marketing_channels AS unique_marketing_channels,
+ SAFE_DIVIDE(1.0, unique_dimension_value_count.marketing_channels) AS linear_multiplier_marketing_channel
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE sm_store_id = 'your-sm_store_id'
+ AND sm_event_name = 'purchase'
+ AND unique_dimension_value_count.marketing_channels IS NOT NULL
+LIMIT 10;
+```
+
+#### Example Scenario
+
+Consider a purchase journey with these touchpoints:
+
+| Session | Channel | Time | Is First Occurrence | Linear Credit |
+|---------|---------|------|-------------------|---------------|
+| Session_1 | Facebook | 9:00 AM | ✓ | 33.3% |
+| Session_1 | Facebook | 9:15 AM | ✗ | 0% |
+| Session_1 | Google | 9:30 AM | ✓ | 33.3% |
+| Session_2 | Facebook | 2:00 PM | ✓ | 33.3% |
+| Session_2 | Facebook | 2:10 PM | ✗ | 0% |
+
+**Result**: 3 unique contributions (Facebook in Session 1, Google in Session 1, Facebook in Session 2) each receive 33.3% credit.
+
+#### Available Deduplication Flags
+
+The model provides `is_first_occurrence_*` flags for all attribution dimensions:
+- `is_first_occurrence_marketing_channel`
+- `is_first_occurrence_ad`
+- `is_first_occurrence_campaign`
+- `is_first_occurrence_ad_group`
+- `is_first_occurrence_landing_page`
+- `is_first_occurrence_email_sms`
+
## Attribution
### Channel Classification Overview
@@ -480,10 +553,10 @@ utm_source=attentive&utm_medium=sms
❌ FB, Paid Social, Summer Sale
```
-**Parameter Hierarchy:**
+**Recommended parameter order:**
-1. Platform IDs (fbadid, gclid)
-2. UTM Parameters
+1. UTM Parameters (utm_source, utm_medium, utm_campaign, etc.)
+2. Platform IDs (fbclid, gclid, ttclid, etc.) as supplemental signals
3. Custom Parameters
**URL Length Considerations:**
diff --git a/mta/mta-brand-campaign-attribution.mdx b/mta/mta-brand-campaign-attribution.mdx
new file mode 100644
index 0000000..e1afffe
--- /dev/null
+++ b/mta/mta-brand-campaign-attribution.mdx
@@ -0,0 +1,137 @@
+---
+title: "Brand Campaign Attribution in MTA"
+sidebarTitle: "Brand Campaign Attribution"
+description: "Understanding how brand campaigns are handled in SourceMedium Multi-Touch Attribution"
+icon: "tag"
+iconType: "solid"
+---
+
+# Brand Campaign Attribution
+
+SourceMedium's MTA system handles brand campaigns differently from non-brand campaigns. This document explains how brand campaigns are treated in attribution models and how to interpret their data.
+
+## What Are Brand Campaigns?
+
+Brand campaigns are marketing initiatives that target users already familiar with your brand, typically using branded search terms, remarketing audiences, or other brand-specific targeting methods. Common examples include:
+
+- Google Search ads for your company name
+- Meta ads targeted at your page's followers
+- Anything considered to boost brand awareness.
+
+We derive brand campaigns from the campaign naming convention. If your campaign name contains "brand", we will automatically categorize it as a brand campaign.
+
+## How Brand Campaigns Are Handled in MTA
+
+In SourceMedium's MTA system, brand campaigns are treated with special rules:
+
+### 1. Zero Attribution Credit
+
+- Brand campaigns appear in performance data but receive **zero attribution credit**
+- The attribution metrics (first-touch, last-touch, linear) are all set to zero
+- This prevents over-attribution to brand terms customers would search for anyway
+
+### 2. Complete Performance Metrics
+
+- All campaign metadata, spend, impressions, and clicks are preserved
+- This allows complete performance reporting alongside attribution metrics
+- You can see exactly how much you're spending on brand campaigns
+
+### 3. Attribution Redistribution
+
+- Attribution credit that would have gone to brand campaigns is redistributed to non-brand touchpoints
+- This provides a more accurate picture of which marketing activities truly drive incremental business
+
+## Brand Campaign Identification
+
+Campaigns are identified as brand campaigns when:
+
+1. Campaign tactic is explicitly set to "brand" (`ad_campaign_tactic = 'brand'`)
+2. Campaign name contains "brand" but not "non-brand"
+3. For search campaigns, when using branded search terms
+
+## Analyzing Brand Campaign Performance
+
+While brand campaigns don't receive attribution credit, they remain important to analyze:
+
+### Metrics to Monitor
+
+- **Traditional Performance**: Clicks, impressions, CTR
+- **Cost Efficiency**: Cost per click, CPM
+- **Platform-Reported Metrics**: Conversions and revenue as reported by the platform
+- **Competitors Bidding**: Whether competitors are targeting your brand terms
+
+### Example Queries
+
+```sql
+-- Brand vs. Non-Brand Campaign Performance
+SELECT
+ CASE
+ WHEN lower(ad_campaign_tactic) = 'brand' THEN 'Brand'
+ ELSE 'Non-Brand'
+ END as campaign_type,
+ SUM(ad_spend) as total_spend,
+ SUM(ad_impressions) as total_impressions,
+ SUM(ad_clicks) as total_clicks,
+ SUM(ad_platform_reported_conversions) as platform_conversions,
+ SUM(ad_platform_reported_revenue) as platform_revenue,
+ SUM(sm_first_touch_revenue) as attributed_revenue,
+ SAFE_DIVIDE(SUM(sm_first_touch_revenue), SUM(ad_spend)) as attributed_roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+GROUP BY 1
+ORDER BY 1
+```
+
+```sql
+-- Brand Campaign Metrics Over Time
+SELECT
+ DATE_TRUNC(date, MONTH) as month,
+ SUM(ad_spend) as brand_spend,
+ SUM(ad_impressions) as brand_impressions,
+ SUM(ad_clicks) as brand_clicks,
+ SAFE_DIVIDE(SUM(ad_clicks), SUM(ad_impressions)) as ctr,
+ SAFE_DIVIDE(SUM(ad_spend), SUM(ad_clicks)) as cpc
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND lower(ad_campaign_tactic) = 'brand'
+ AND date >= DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH)
+GROUP BY 1
+ORDER BY 1
+```
+
+## Business Implications
+
+### Why Brand Campaigns Receive Zero Attribution
+
+1. **Incremental Value**: Brand campaigns often target users who would have found you anyway
+2. **Last-Click Bias**: Brand campaigns typically occur late in the customer journey
+3. **Budget Allocation**: Attributing to brand campaigns can lead to overinvestment in non-incremental marketing
+
+### When Brand Campaigns Matter
+
+Despite receiving zero attribution credit, brand campaigns can still be valuable:
+
+- **Competitive Defense**: Protecting your brand terms from competitors
+- **Return Path Creation**: Providing an easy way back for customers considering your brand
+- **Remarketing Efficiency**: Re-engaging visitors who showed previous interest
+
+### Balanced Approach to Brand Campaigns
+
+SourceMedium's approach allows you to:
+
+1. **See Complete Data**: All brand campaign performance metrics are visible
+2. **Make Informed Decisions**: Compare platform-reported vs. attributed metrics
+3. **Proper Budget Allocation**: Invest in truly incremental marketing while maintaining appropriate brand presence
+
+## Customizing Brand Campaign Handling
+
+If your business has unique requirements for brand campaign attribution, SourceMedium can implement custom rules. Some options include:
+
+- **Partial Attribution**: Allowing brand campaigns to receive some attribution credit
+- **Custom Brand Definition**: Refining what constitutes a "brand" campaign for your business
+- **Advanced Models**: Implementing incrementality testing or other advanced attribution approaches
+
+Contact your SourceMedium account manager to discuss customization options that might be right for your business.
diff --git a/mta/mta-channel-level-attribution.mdx b/mta/mta-channel-level-attribution.mdx
new file mode 100644
index 0000000..3b8eeba
--- /dev/null
+++ b/mta/mta-channel-level-attribution.mdx
@@ -0,0 +1,177 @@
+---
+title: "Channel-Level Attribution & Unattributed Metrics"
+sidebarTitle: "Channel-Level Attribution"
+description: "Understanding channel-level attribution and unattributed metrics in SourceMedium MTA"
+icon: "chart-column"
+iconType: "solid"
+---
+
+# Channel-Level Attribution & Unattributed Metrics
+
+SourceMedium's MTA system provides a complete view of marketing performance by combining ad-level attribution with channel-level metrics. This approach ensures that all marketing spend is accounted for, even when specific ads cannot be directly attributed.
+
+## Ad-Level vs. Channel-Level Data
+
+The MTA system organizes marketing data at two levels:
+
+### Ad-Level Data
+
+- **Granularity**: Individual ad creatives identified by `ad_id`
+- **Content**: Complete ad metadata, performance metrics, and attribution metrics
+- **Attribution**: Full attribution across first-touch, last-touch, and linear models
+- **Identification**: Records where `ad_id` is present and `sm_marketing_channel` is NULL
+
+### Channel-Level Data
+
+- **Granularity**: Marketing channels (Facebook, Google, etc.) identified by `sm_marketing_channel`
+- **Content**: Only unattributed spend, impressions, and clicks not already counted at the ad level
+- **Purpose**: Account for marketing activity that cannot be tied to specific ads
+- **Identification**: Records where `sm_marketing_channel` is present and `ad_id` is NULL
+
+## Unattributed Channel Metrics
+
+To prevent double-counting while ensuring complete marketing visibility, channel-level rows in the `rpt_ad_attribution_performance_daily` model contain only "unattributed" metrics:
+
+### What Are Unattributed Metrics?
+
+Unattributed metrics represent marketing activities that:
+1. Cannot be tied to a specific ad ID
+2. Are not already counted in ad-level metrics
+3. Still contribute to overall marketing spend and performance
+
+### Key Unattributed Metrics
+
+- `unattributed_channel_spend`: Marketing spend not associated with specific ads
+- `unattributed_channel_impressions`: Impressions not associated with specific ads
+- `unattributed_channel_clicks`: Clicks not associated with specific ads
+
+## How Unattributed Metrics Are Calculated
+
+The calculation of unattributed metrics follows this process:
+
+1. **Total Channel Metrics**: Calculate total spend, impressions, and clicks for each channel
+2. **Ad-Level Metrics**: Calculate the sum of these metrics for all ads in the channel
+3. **Unattributed Metrics**: Subtract ad-level metrics from total channel metrics
+
+This approach ensures that:
+- No metric is counted twice
+- All marketing spend is accounted for
+- Channel-level analysis is complete and accurate
+
+## Analyzing Channel and Ad-Level Data Together
+
+When analyzing marketing performance, it's important to consider both ad-level and channel-level data:
+
+### Complete Channel Analysis
+
+To get a complete view of a channel's performance:
+
+```sql
+-- Complete channel performance including attributed and unattributed metrics
+SELECT
+ COALESCE(sm_channel, 'Unknown') as channel,
+ SUM(ad_spend) as total_spend,
+ SUM(ad_impressions) as total_impressions,
+ SUM(ad_clicks) as total_clicks,
+ SUM(sm_first_touch_revenue) as first_touch_revenue,
+ SUM(sm_last_touch_revenue) as last_touch_revenue,
+ SUM(sm_linear_revenue) as linear_revenue,
+ SAFE_DIVIDE(SUM(sm_first_touch_revenue), SUM(ad_spend)) as first_touch_roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+GROUP BY 1
+ORDER BY 2 DESC
+```
+
+### Ad-Level Detail
+
+For granular analysis of the specific ads driving performance:
+
+```sql
+-- Ad-level performance for a specific channel
+SELECT
+ ad_name,
+ ad_campaign_name,
+ SUM(ad_spend) as ad_spend,
+ SUM(ad_impressions) as impressions,
+ SUM(ad_clicks) as clicks,
+ SUM(sm_first_touch_revenue) as first_touch_revenue,
+ SUM(sm_last_touch_revenue) as last_touch_revenue,
+ SUM(sm_linear_revenue) as linear_revenue,
+ SAFE_DIVIDE(SUM(sm_linear_revenue), SUM(ad_spend)) as linear_roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND source_system = 'facebook' -- or other channel
+ AND ad_id IS NOT NULL -- Only ad-level data
+GROUP BY 1, 2
+ORDER BY 9 DESC -- Ordered by ROAS
+```
+
+### Unattributed Analysis
+
+To specifically analyze unattributed spend within channels:
+
+```sql
+-- Unattributed metrics by channel
+SELECT
+ sm_channel as channel,
+ SUM(ad_spend) as unattributed_spend,
+ SUM(ad_impressions) as unattributed_impressions,
+ SUM(ad_clicks) as unattributed_clicks
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND sm_channel IS NOT NULL
+ AND ad_id IS NULL -- Only channel-level unattributed data
+GROUP BY 1
+ORDER BY 2 DESC
+```
+
+## Business Value of Unattributed Metrics
+
+Including unattributed metrics in the MTA system provides several business benefits:
+
+### 1. Complete Marketing Picture
+
+- **Total Cost Visibility**: Account for all marketing spend, not just ad-level spend
+- **Performance Context**: Understand channel performance holistically
+- **Budget Validation**: Reconcile platform-reported spend with actual spend
+
+### 2. Accurate Attribution Metrics
+
+- **No Double-Counting**: Attribution metrics remain accurate by avoiding duplication
+- **Clean Data Separation**: Ad-level and channel-level data remain distinct
+- **Proper Denominator**: ROI/ROAS calculations use correct total spend figures
+
+### 3. Marketing Mix Insights
+
+- **Channel Efficiency**: Compare attributed and unattributed spend by channel
+- **Data Quality Gaps**: Identify channels with high unattributed percentages
+- **Optimization Opportunities**: Focus on reducing unattributed spend through better tracking
+
+## Frequently Asked Questions
+
+### Why do some channels have high unattributed spend?
+
+Channels may have high unattributed spend due to:
+- Poor UTM parameter implementation
+- API limitations not providing ad-level data
+- Manual or offline marketing activities
+- Technical tracking limitations
+
+### How can I reduce unattributed spend?
+
+To reduce unattributed spend:
+- Implement consistent UTM parameters across all campaigns
+- Use dedicated tracking links for offline campaigns
+- Ensure proper API connections for all platforms
+- Work with your SourceMedium account manager to improve tracking
+
+### Can unattributed spend receive attribution?
+
+Unattributed spend cannot directly receive attribution in the MTA system since it cannot be tied to specific touchpoints in customer journeys. However, it's still included in overall channel metrics to provide complete performance visibility.
diff --git a/mta/mta-dash-provisioning.mdx b/mta/mta-dash-provisioning.mdx
index c242ca9..9eb7da5 100644
--- a/mta/mta-dash-provisioning.mdx
+++ b/mta/mta-dash-provisioning.mdx
@@ -1,11 +1,11 @@
---
-title: "How to Self-Service Provision Your Source Medium MTA Dashboard"
+title: "How to Self-Service Provision Your SourceMedium MTA Dashboard"
+description: "How to copy the MTA Looker Studio template and connect it to your warehouse data sources."
sidebarTitle: "MTA Dash Provisioning"
icon: "chart-bar"
iconType: "solid"
---
-
-To access Source Medium’s built-in multi-touch reporting, you’ll need to provision your dashboard. Dashboard provisioning is easy to do using Source Medium’s [template](https://lookerstudio.google.com/s/kN_l7dBHU1k) and the Looker Studio copying feature, just follow the steps below.
+To access SourceMedium’s built-in multi-touch reporting, you’ll need to provision your dashboard. Dashboard provisioning is easy to do using SourceMedium’s [template](https://lookerstudio.google.com/s/kN_l7dBHU1k) and the Looker Studio copying feature, just follow the steps below.
The video below contains the same information as the guide, choose whatever format you prefer!
@@ -23,9 +23,9 @@ To access Source Medium’s built-in multi-touch reporting, you’ll need to pro
- Make sure you’ve gotten confirmation from a Source Medium team member via Slack or email that your MTA data has been modeled and is present in your warehouse.
+ Make sure you’ve gotten confirmation from a SourceMedium team member via Slack or email that your MTA data has been modeled and is present in your warehouse.
- Once you have confirmation your data is ready, navigate to the demo dashboard for the latest release of Source Medium’s MTA reporting, which you can find at the link [here](https://lookerstudio.google.com/s/kN_l7dBHU1k). If you have any issues accessing the dashboard, reach out to a Source medium team member via Slack or email.
+ Once you have confirmation your data is ready, navigate to the demo dashboard for the latest release of SourceMedium’s MTA reporting, which you can find at the link [here](https://lookerstudio.google.com/s/kN_l7dBHU1k). If you have any issues accessing the dashboard, reach out to a Source medium team member via Slack or email.
@@ -55,16 +55,16 @@ To access Source Medium’s built-in multi-touch reporting, you’ll need to pro
- After you’ve begun creating the new data source, select the **Big Query** connector.
+ After you’ve begun creating the new data source, select the **BigQuery** connector.
- With the **Big Query** connector selected, select:
+ With the **BigQuery** connector selected, select:
- Project: **SM Managed - Your Company Name**
- Dataset: **sm_experimental**
- - Table: **obt_purchase_journeys_with_mta_models** or **rpt_attribution_channel_mapping_summary** or **rpt_attribution_performance_daily**
+ - Table: **obt_purchase_journeys_with_mta_models** or **rpt_ad_attribution_performance_daily**
- After you’ve selected the correct Project, Dataset, and Table, click **Connect** and then **Add to Report** on the next screen to add the data source
@@ -103,7 +103,7 @@ To access Source Medium’s built-in multi-touch reporting, you’ll need to pro
- If you wish to do so, you may replace the Source Medium icon in the top left by clicking on it and then clicking the name of the default file in the **Image Properties** panel on the right. You will be prompted to select a new file from your computer. The icon is linked to all dashboard pages, so you only need to do this once.
+ If you wish to do so, you may replace the SourceMedium icon in the top left by clicking on it and then clicking the name of the default file in the **Image Properties** panel on the right. You will be prompted to select a new file from your computer. The icon is linked to all dashboard pages, so you only need to do this once.
@@ -118,9 +118,9 @@ To access Source Medium’s built-in multi-touch reporting, you’ll need to pro
- You are now ready to use Source Medium's built-in multi-touch attribution reporting. Happy analyzing!
+ You are now ready to use SourceMedium's built-in multi-touch attribution reporting. Happy analyzing!
- If you'd like to learn more about the basics of Source Medium MTA, read our [MTA Overview](/mta/mta-overview)
+ If you'd like to learn more about the basics of SourceMedium MTA, read our [MTA Overview](/mta/mta-overview)For answers to common MTA questions check out our [MTA FAQs](/mta/mta-faqs) or use the AI-enabled search bar above to quickly find what you’re looking for.
diff --git a/mta/mta-email-sms-attribution.mdx b/mta/mta-email-sms-attribution.mdx
new file mode 100644
index 0000000..4576295
--- /dev/null
+++ b/mta/mta-email-sms-attribution.mdx
@@ -0,0 +1,141 @@
+---
+title: "Email & SMS Attribution in SourceMedium MTA"
+sidebarTitle: "Email & SMS Attribution"
+description: "Understanding how Email and SMS messages are handled in SourceMedium Multi-Touch Attribution"
+icon: "envelope"
+iconType: "solid"
+---
+
+# Email & SMS Attribution
+
+SourceMedium's MTA system handles Email and SMS channels differently from other marketing channels. This special treatment is designed to provide a more accurate picture of acquisition performance while still recognizing the conversion power of owned marketing channels.
+
+## Special Attribution Rules for Email & SMS
+
+### Why Email/SMS Attribution Works Differently
+
+Email and SMS are unique marketing channels because:
+
+1. **Existing Relationship Required**: Unlike acquisition channels, Email and SMS require a prior relationship with the customer.
+2. **Skewed Attribution**: Without special rules, Email/SMS often receives disproportionate credit in first-touch and linear models.
+3. **Over-attribution Risk**: Including Email/SMS in all attribution models can lead to under-valuing true acquisition channels.
+
+### Email/SMS Attribution Rules
+
+To address these unique characteristics, SourceMedium MTA applies the following rules:
+
+1. **First-Touch Attribution**:
+ - Email/SMS channels do not receive first-touch attribution credit
+ - Credit goes to the earliest non-Email/SMS touch point instead
+ - For journeys with only Email/SMS touches, no first-touch attribution is assigned
+
+2. **Linear Attribution**:
+ - Email/SMS touches are excluded from linear attribution
+ - Credit is distributed only among non-Email/SMS touches
+ - For journeys with only Email/SMS touches, no linear attribution is assigned
+
+3. **Last-Touch Attribution**:
+ - Special customer-specific rules apply
+ - By default, Email/SMS is excluded from last-touch attribution
+ - For specific customers (currently only Elix Healing), Email/SMS can receive last-touch attribution
+ - This configuration is managed via the `is_email_sms_last_touch_enabled` setting
+
+4. **Email/SMS-Only Journeys**:
+ - Journeys where *all* touches are Email/SMS are generally not attributable
+ - These journeys show as "unattributed" in attribution reports
+ - Exception: Last-touch attribution for specific customers
+
+## Dedicated Email/SMS Dimension
+
+To provide visibility into Email and SMS performance while maintaining these special rules, SourceMedium MTA includes a dedicated "email_sms" dimension.
+
+### Email/SMS Dimension Features
+
+- **Message ID Extraction**: Identifies specific email or SMS messages using:
+ 1. `utm_id` (primary - used by Klaviyo and other ESPs)
+ 2. `utm_content` (fallback option)
+ 3. `utm_term` (secondary fallback)
+
+- **Display Format**: `[channel]message_id`
+ - Example: "[email]123456" or "[sms]789012"
+
+- **Connection to Message Performance**: Links to engagement metrics from `rpt_outbound_message_performance_daily`
+
+### Benefits of the Dedicated Dimension
+
+This approach provides the best of both worlds:
+- **Acquisition Accuracy**: By excluding Email/SMS from first touch and linear models, you get a clearer picture of which channels truly acquire customers
+- **Email/SMS Visibility**: Through the dedicated dimension, you still see the impact of Email/SMS on conversions
+- **Flexible Customer Configuration**: Customer-specific settings allow for business model adaptations
+
+## Analyzing Email/SMS Performance
+
+### Attribution Reports
+
+While Email/SMS channels generally do not receive attribution in first-touch and linear models, you can still analyze their performance:
+
+1. **Last-Touch Analysis** (for enabled customers):
+ - See which Email/SMS messages are most effective at closing sales
+ - Compare last-touch attribution to Email/SMS performance metrics
+
+2. **Email/SMS Dimension Analysis**:
+ - Track which messages appear in customer journeys
+ - Identify the Email/SMS messages most frequently associated with purchases
+
+### Example Analysis Queries
+
+```sql
+-- Email messages that appear most frequently in purchase journeys
+SELECT
+ dimension_value.email_sms as message_id,
+ COUNT(DISTINCT purchase_order_id) as journey_count
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND dimension_value.email_sms IS NOT NULL
+GROUP BY 1
+ORDER BY 2 DESC
+LIMIT 20
+```
+
+```sql
+-- Email performance metrics with last-touch attribution
+-- (only for customers with Email/SMS last-touch enabled)
+ SELECT
+ r.campaign_name,
+ COUNT(DISTINCT r.message_id) as message_count,
+ SUM(r.message_unique_receives) as deliveries,
+ SUM(r.message_unique_opens) as opens,
+ SUM(r.message_unique_clicks) as clicks,
+ SUM(a.last_touch_revenue) as last_touch_revenue,
+ SAFE_DIVIDE(SUM(a.last_touch_revenue), NULLIF(SUM(r.message_unique_receives), 0)) as revenue_per_delivery
+ FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily` r
+ LEFT JOIN (
+ SELECT
+ dimension_value.email_sms as message_id,
+ SUM(last_touch_revenue_impact.email_sms) as last_touch_revenue
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND sm_event_name = 'purchase'
+ AND last_touch_revenue_impact.email_sms > 0
+ GROUP BY 1
+) a ON r.message_id = a.message_id
+WHERE
+ r.sm_store_id = 'your-sm_store_id'
+ AND r.sm_message_channel IN ('email', 'sms')
+ AND r.date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+GROUP BY 1
+ORDER BY 7 DESC
+```
+
+## Business Impact
+
+These Email/SMS attribution rules provide several business benefits:
+
+1. **More Accurate Channel Valuation**: Acquisition channels get proper credit for bringing in new customers
+2. **Better Budget Allocation**: Prevents overinvestment in email at the expense of true acquisition channels
+3. **Clearer Marketing Funnel**: Distinguishes between acquisition and retention/conversion channels
+4. **Adaptable to Business Models**: Customer-specific settings accommodate different business needs
+
+For businesses where Email/SMS plays a significant role in acquisition (e.g., referral programs delivered via email), custom attribution rules can be implemented. Contact your SourceMedium account manager to discuss your specific needs.
diff --git a/mta/mta-faqs.mdx b/mta/mta-faqs.mdx
index e5f8a14..e7079c3 100644
--- a/mta/mta-faqs.mdx
+++ b/mta/mta-faqs.mdx
@@ -1,15 +1,15 @@
---
-title: "Source Medium Multi-Touch Attribution FAQs"
+title: "SourceMedium Multi-Touch Attribution FAQs"
sidebarTitle: "MTA FAQs"
-description: "Find the answers to commonly asked questions about Source Medium Multi-Touch Attribution"
+description: "Find the answers to commonly asked questions about SourceMedium Multi-Touch Attribution"
icon: "question"
iconType: "solid"
---
-
- Source Medium MTA takes multiple data sources reporting many customer journeys, unifies them into a single schema and assesses their quality, then combines the best of those purchase journeys with Marketing Data, Orders Data, Customer Data, and User Inputs to create a Unified Purchase Journey Dataset. View this process in the figure below.
+
+ SourceMedium MTA takes multiple data sources reporting many customer journeys, unifies them into a single schema and assesses their quality, then combines the best of those purchase journeys with Marketing Data, Orders Data, Customer Data, and User Inputs to create a Unified Purchase Journey Dataset. View this process in the figure below.
**Purchase Journey Data Sources include:** Google Analytics, Elevar, Blotout, Littledata, Heap, Amplitude, PostHog, Snowplow, Tapcart
@@ -19,7 +19,7 @@ iconType: "solid"
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
@@ -29,7 +29,7 @@ iconType: "solid"
_Example:_ A pie chart showing **Marketing Channel Attributable Revenue** is displaying the percentage of Revenue for which at least one touch point exists, when viewing touch points of the Marketing Channel (mapped UTM) type
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
@@ -37,17 +37,17 @@ iconType: "solid"
_Example:_ A customer visits the same landing page 3 separate times on 3 separate dates before making a purchase. This purchase journey contains 3 landing page touch points, but only 1 **Distinct Dimension Value** for the landing page model dimension, as the landing pages were not unique.
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
- A **purchase journey** includes all recorded touch points leading up to a purchase made by a customer, an example is displayed in the figure below
- - Source Medium MTA standardizes purchase journeys to the [GA4 E-Commerce Event Schema](https://support.google.com/analytics/answer/9267735?hl=en) that you may already be familiar with
- - There are often many data sources reporting many purchase journeys for each purchase, Source Medium MTA selects the highest quality purchase journey available by number of valid touch points—read more on this in the modeling section below
+ - SourceMedium MTA standardizes purchase journeys to the [GA4 E-Commerce Event Schema](https://support.google.com/analytics/answer/9267735?hl=en) that you may already be familiar with
+ - There are often many data sources reporting many purchase journeys for each purchase, SourceMedium MTA selects the highest quality purchase journey available by number of valid touch points—read more on this in the modeling section below
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
@@ -55,30 +55,228 @@ iconType: "solid"
Marketing interactions happen with customers in the form of **touch points**—many touch points make up a **purchase journey**, and many purchase journeys make up a **multi-touch attribution data set**. Click the tabs below to read more about each of these concepts.
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
-
- **Source Medium MTA Built-in Reports** are part of a standalone dashboard separate from your main Source Medium dash. After MTA is enabled for your account, the dashboard link will be pinned to your shared Slack channel or sent via email/gchat if you do not use Slack.
+
+ **SourceMedium MTA Built-in Reports** are part of a standalone dashboard separate from your main SourceMedium dash. After MTA is enabled for your account, the dashboard link will be pinned to your shared Slack channel or sent via email/gchat if you do not use Slack.
For a description of each of the default modules and their functionality, see the Built-in Reporting dropdown from section 3 of our [MTA Overview](/mta/mta-overview)
-
- - Source Medium MTA modeling enables three different attribution types:
+
+ - SourceMedium MTA modeling enables three different attribution types:
- **First Touch:** Assigns all credit to the first valid touch point in the purchase journey
- **Last Touch:** Assigns all credit to the last valid touch point before the purchase
- **Linear:** Distributes credit equally among all valid touch points
_Example:_ A purchase journey in which the customer first interacted with a Google ad, second a TikTok ad, and third a Meta ad before then making a purchase would give credit solely to Google via **First Touch Attribution**, and would give credit solely to Meta via **Last Touch Attribution**—but would distribute one third of the credit each to Google, Meta, and TikTok via **Linear Attribution**.
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the basics of SourceMedium MTA in our [MTA Overview](/mta/mta-overview)
+
+
+
+ Email and SMS channels are excluded from first touch and linear attribution for several important reasons:
+
+ 1. **Existing Relationship Required**: By definition, Email and SMS require a customer to have already interacted with your brand (to provide their contact information), so they're rarely the true "first touch" in a customer's journey.
+
+ 2. **Marketing Budget Allocation**: Including Email/SMS in all attribution models can lead to undervaluing true acquisition channels, causing misallocation of marketing budgets.
+
+ 3. **Frequent Touches**: Email and SMS often have multiple touches in a journey, which can disproportionately influence linear attribution.
+
+ Instead, SourceMedium provides a dedicated Email/SMS dimension that allows you to analyze the impact of these channels separately, while maintaining more accurate attribution for acquisition channels.
+
+ For more details, see our [Email & SMS Attribution](/mta/mta-email-sms-attribution) documentation.
+
+
+
+ Brand campaigns receive zero attribution credit in SourceMedium's MTA system because:
+
+ 1. **Incremental Value**: Brand campaigns typically target users who would have found you anyway (searching specifically for your brand name).
+
+ 2. **Last-Click Bias**: In traditional models, brand campaigns often receive disproportionate credit simply because they occur late in the purchase journey.
+
+ 3. **Marketing Budget Optimization**: Attributing conversions to brand campaigns can lead to overinvestment in non-incremental marketing and underinvestment in true acquisition channels.
+
+ However, brand campaign metrics (spend, impressions, clicks) are still fully visible in the system. This approach gives you complete transparency into your marketing activities while preventing attribution bias.
+
+ For more details, see our [Brand Campaign Attribution](/mta/mta-brand-campaign-attribution) documentation.
+
+
+
+ SourceMedium's MTA system organizes marketing data at two distinct levels:
+
+ **Ad-Level Data**:
+ - Identified by specific `ad_id` values
+ - Contains complete ad metadata and performance metrics
+ - Receives attribution credit across all models
+ - Represents marketing activities that can be tied to specific creative assets
+
+ **Channel-Level Data**:
+ - Identified by `sm_marketing_channel` (e.g., Facebook, Google)
+ - Contains only unattributed metrics not already counted at the ad level
+ - Represents marketing activities that cannot be tied to specific ads
+ - Prevents double-counting while maintaining complete spend visibility
+
+ This dual approach ensures you have both granular ad-level insights and complete channel-level spend accountability.
+
+ For more details, see our [Channel-Level Attribution & Unattributed Metrics](/mta/mta-channel-level-attribution) documentation.
+
+
+
+ The Email/SMS dimension is a specialized attribution dimension specifically designed for tracking and analyzing the impact of email and SMS messages on purchase journeys.
+
+ Key features include:
+ - **Message ID Extraction**: Identifies specific messages using utm_id, utm_content, or utm_term parameters
+ - **Display Format**: Uses a standardized [channel]message_id format (e.g., "[email]123456")
+ - **Performance Connection**: Links to engagement metrics from outbound message performance data
+ - **Attribution Rules**: Has its own specific attribution logic, separate from the marketing channel dimension
+
+ This dedicated dimension allows you to analyze email and SMS performance in detail, even while these channels are excluded from first touch and linear attribution in the marketing channel dimension.
+
+ For more details, see our [Email & SMS Attribution](/mta/mta-email-sms-attribution) documentation.
- Needs answer. To include verifying GA4 setup, links to Google Analytics documentation.
+ To improve your attribution rate (the percentage of purchases with attributable touchpoints), consider these approaches:
+
+ 1. **Implement Proper UTM Parameters**:
+ - Ensure all marketing campaigns use consistent UTM parameters
+ - Add UTM parameters to email and SMS links
+ - Use unique campaign and content identifiers
+
+ 2. **Connect Additional Data Sources**:
+ - Integrate all your marketing platforms with SourceMedium
+ - Enable event tracking on your website and app
+ - Consider implementing a Customer Data Platform (CDP) (see [Customer Record Enrichment](/help-center/core-concepts/customer-record-enrichment/index))
+
+ 3. **Optimize Tracking Setup**:
+ - Verify your Google Analytics configuration
+ - Implement server-side tracking where possible
+ - Ensure cross-domain tracking is properly configured
+
+ 4. **Review Attribution Windows**:
+ - Standard attribution window is 90 days
+ - Extending this window may capture more touchpoints
+ - Work with your SourceMedium account manager to adjust if needed
+
+ For technical assistance with improving attribution rates, contact your SourceMedium account manager.
+
+
+
+ Yes, SourceMedium can implement custom attribution rules tailored to your business model. Common customizations include:
+
+ 1. **Email/SMS Attribution Rules**:
+ - Enabling Email/SMS in last-touch attribution
+ - Customizing which message types receive attribution
+ - Special handling for referral or affiliate emails
+
+ 2. **Brand Campaign Configuration**:
+ - Customizing what qualifies as a "brand" campaign
+ - Implementing partial attribution for brand campaigns
+ - Creating brand-specific attribution models
+
+ 3. **Attribution Windows**:
+ - Adjusting lookback periods for specific product categories
+ - Setting different windows for different attribution models
+ - Configuring business-specific conversion cycles
+
+ 4. **Custom Dimensions**:
+ - Creating industry-specific attribution dimensions
+ - Implementing custom weighting factors
+ - Building customer segment-specific models
+
+ To discuss custom attribution configurations, contact your SourceMedium account manager.
+
+
+
+ Unattributed spend represents marketing activities that cannot be tied to specific ads but still contributes to overall marketing costs. To analyze this spend:
+
+ 1. **Identify Channel-Level Rows**:
+ - Look for rows where `sm_marketing_channel` is present but `ad_id` is NULL
+ - These rows contain only the unattributed portion of each channel's metrics
+
+ 2. **Run Analysis Queries**:
+ ```sql
+ -- Unattributed spend by channel
+ SELECT
+ sm_channel as channel,
+ SUM(ad_spend) as unattributed_spend
+ FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+ WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND sm_channel IS NOT NULL
+ AND ad_id IS NULL -- Only channel-level data
+ GROUP BY 1
+ ORDER BY 2 DESC
+ ```
+
+ 3. **Calculate Unattributed Percentage**:
+ ```sql
+ -- Percentage of spend that is unattributed by channel
+ WITH channel_totals AS (
+ SELECT
+ COALESCE(sm_channel, 'Unknown') as channel,
+ SUM(ad_spend) as total_spend
+ FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+ WHERE sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ GROUP BY 1
+ ),
+ unattributed AS (
+ SELECT
+ sm_channel as channel,
+ SUM(ad_spend) as unattributed_spend
+ FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+ WHERE sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND sm_channel IS NOT NULL
+ AND ad_id IS NULL
+ GROUP BY 1
+ )
+ SELECT
+ t.channel,
+ t.total_spend,
+ COALESCE(u.unattributed_spend, 0) as unattributed_spend,
+ SAFE_DIVIDE(COALESCE(u.unattributed_spend, 0), t.total_spend) * 100 as unattributed_percent
+ FROM channel_totals t
+ LEFT JOIN unattributed u ON t.channel = u.channel
+ ORDER BY 4 DESC
+ ```
+
+ For more details, see our [Channel-Level Attribution & Unattributed Metrics](/mta/mta-channel-level-attribution) documentation.
+
+
+
+ Linear attribution uses **session-based deduplication** to ensure each unique marketing contribution is counted appropriately, avoiding over-attribution to repetitive interactions.
+
+ **Real-World Example:**
+
+ Imagine a customer's day:
+ - **Morning (Session 1)**: Clicks Facebook ad 3 times while browsing with coffee
+ - **Afternoon (Session 2)**: Searches Google and clicks your ad once
+ - **Evening (Session 3)**: Clicks Facebook ad again before purchasing
+
+ **How Linear Attribution Credits This Journey:**
+
+
+ **Before Deduplication**: All 5 clicks would share credit equally (20% each)
+
+ **After Deduplication**: Only 3 unique contributions receive credit:
+ - Facebook (Session 1): 33.3%
+ - Google (Session 2): 33.3%
+ - Facebook (Session 3): 33.3%
+
+
+ **Why This Matters:**
+ - **More Accurate**: Reflects true marketing effectiveness, not just click volume
+ - **Better Insights**: Shows which channels drive unique engagement vs. repetitive interactions
+ - **Smarter Budgeting**: Helps identify channels that genuinely influence purchase decisions
+
+ **Technical Note**: This deduplication applies to all attribution dimensions - marketing channels, ads, campaigns, ad groups, landing pages, and email/SMS. Each dimension tracks its own "first occurrence" within sessions.
- Learn more about the basics of Source Medium MTA in our [MTA Overview](/mta/mta-overview)
+ Learn more about the technical implementation in our [MTA Advanced Documentation](/mta/mta-advanced-documentation#linear-attribution-deduplication)
-
\ No newline at end of file
+
diff --git a/mta/mta-models.mdx b/mta/mta-models.mdx
new file mode 100644
index 0000000..f9d0fb5
--- /dev/null
+++ b/mta/mta-models.mdx
@@ -0,0 +1,255 @@
+---
+title: "SourceMedium MTA Models Reference"
+sidebarTitle: "MTA Models Reference"
+description: "Understanding the core data models that power SourceMedium Multi-Touch Attribution"
+icon: "database"
+iconType: "solid"
+---
+
+# Multi-Touch Attribution Data Models
+
+SourceMedium's Multi-Touch Attribution system is built on several powerful data models that track customer journeys, calculate attribution, and provide insights into marketing performance. This guide explains the core models you can use for analysis and reporting.
+
+## Core Attribution Models
+
+### Purchase Journeys with MTA Models (`obt_purchase_journeys_with_mta_models`)
+
+This is the central model for multi-touch attribution, containing complete customer journey data with attribution calculations across multiple models and dimensions.
+
+#### Key Columns
+
+- **Identifiers**
+ - `sm_store_id`: SourceMedium store identifier (brand/workspace; formerly `smcid`)
+ - `source_system`: Original tracking source (Elevar, Blotout, etc.)
+ - `sm_touch_id`: Unique identifier for each touch point
+ - `purchase_order_id`: Associated order ID for purchase events
+
+- **Event Data**
+ - `sm_event_name`: Standardized event name
+ - `event_local_datetime`: Timestamp in customer's local timezone
+ - `sm_event_marketing_channel`: Marketing channel classification
+ - `sm_event_ad_id`: Ad identifier
+ - `sm_event_page_category`: Page category classification
+ - `sm_event_page_path`: Page path from the event
+
+- **Attribution Metadata**
+ - `attribution_metadata`: Contains UTM parameters and referrer information
+ - `has_non_email_sms_touch`: Indicates if journey has non-email/SMS touches
+ - `days_to_conversion`: Days between touch and conversion
+ - `purchase_journey_type`: Classification of the journey (single session, multi-session, etc.)
+
+- **Revenue Impact Metrics**
+ - `first_touch_revenue_impact`: Revenue attributed by first touch model for each dimension
+ - `last_touch_revenue_impact`: Revenue attributed by last touch model for each dimension
+ - `linear_revenue_impact`: Revenue attributed by linear model for each dimension
+
+- **Conversion Impact Metrics**
+ - `first_touch_conversion_impact`: Conversions attributed by first touch model
+ - `last_touch_conversion_impact`: Conversions attributed by last touch model
+ - `linear_conversion_impact`: Conversions attributed by linear model
+
+- **Deduplication Flags** *(New in v1.34)*
+ - `is_first_occurrence_marketing_channel`: Indicates if this is the first occurrence of the marketing channel in the session
+ - `is_first_occurrence_ad`: Indicates if this is the first occurrence of the ad in the session
+ - `is_first_occurrence_campaign`: Indicates if this is the first occurrence of the campaign in the session
+ - `is_first_occurrence_ad_group`: Indicates if this is the first occurrence of the ad group in the session
+ - `is_first_occurrence_landing_page`: Indicates if this is the first occurrence of the landing page in the session
+ - `is_first_occurrence_email_sms`: Indicates if this is the first occurrence of the email/SMS in the session
+
+#### Special Features
+
+- **Email/SMS Handling**: The model implements special rules for Email/SMS channels
+ - Email/SMS touches are excluded from first touch and linear attribution
+ - Email/SMS can receive last touch attribution for specific customers
+ - A dedicated email_sms dimension tracks these touches separately
+
+- **Brand Campaign Handling**: Brand campaigns appear in data but receive zero attribution
+
+- **Session-Based Deduplication**: Linear attribution uses the `is_first_occurrence_*` flags to ensure unique contributions per session
+
+#### Example Queries
+
+**Analyze Linear Attribution Deduplication**
+```sql
+-- See how deduplication affects a specific purchase journey
+WITH journey_details AS (
+ SELECT
+ purchase_order_id,
+ dimension_value.marketing_channel,
+ event_local_datetime,
+ linear_revenue_impact.marketing_channel as linear_revenue,
+ purchase_order_revenue
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND purchase_order_id = 'ORDER_ID_HERE'
+ AND dimension_value.marketing_channel IS NOT NULL
+ ORDER BY event_local_datetime
+)
+SELECT *
+FROM journey_details;
+```
+
+**Standard Attribution Queries**
+
+```sql
+-- Revenue by marketing channel (first touch model)
+SELECT
+ dimension_value.marketing_channel,
+ SUM(first_touch_revenue_impact.marketing_channel) as first_touch_revenue
+FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND first_touch_revenue_impact.marketing_channel > 0
+GROUP BY 1
+ORDER BY 2 DESC
+```
+
+### Ad Attribution Performance Daily (`rpt_ad_attribution_performance_daily`)
+
+This report model combines ad performance data with attribution metrics at both ad and channel levels, providing a comprehensive view of marketing performance.
+
+#### Key Columns
+
+- **Identifiers & Dimensions**
+ - `sm_store_id`: SourceMedium store identifier (brand/workspace; formerly `smcid`)
+ - `source_system`: Ad platform source
+ - `date`: Performance date
+ - `sm_marketing_channel`: Marketing channel (only for channel-level rows)
+ - `ad_id`: Ad identifier (only for ad-level rows)
+
+- **Ad Metadata**
+ - `ad_name`: Name of the ad
+ - `ad_campaign_id`: Campaign identifier
+ - `ad_campaign_name`: Campaign name
+ - `ad_campaign_type`: Campaign type
+ - `ad_campaign_tactic`: Campaign tactic (e.g., "brand", "prospecting")
+
+- **Performance Metrics**
+ - `ad_spend`: Amount spent on the ad
+ - `ad_clicks`: Number of clicks
+ - `ad_impressions`: Number of impressions
+ - `ad_platform_reported_conversions`: Conversions reported by the platform
+ - `ad_platform_reported_revenue`: Revenue reported by the platform
+
+- **Attribution Metrics**
+ - `sm_first_touch_revenue`: Revenue attributed via first touch model
+ - `sm_last_touch_revenue`: Revenue attributed via last touch model
+ - `sm_linear_revenue`: Revenue attributed via linear model
+ - `sm_first_touch_conversions`: Conversions attributed via first touch model
+ - `sm_last_touch_conversions`: Conversions attributed via last touch model
+ - `sm_linear_conversions`: Conversions attributed via linear model
+
+#### Special Features
+
+- **Channel-Level Unattributed Metrics**
+ - Channel-level rows (where `ad_id` is NULL) only include unattributed metrics not counted at the ad level
+ - This prevents double-counting while providing complete marketing spend visibility
+
+- **Brand Campaign Handling**
+ - Brand campaigns appear in the data with spend, impressions, and clicks
+ - Attribution metrics for brand campaigns are set to zero
+ - This allows full visibility into brand campaign performance while preventing attribution
+
+#### Example Queries
+
+```sql
+-- ROAS by Campaign (Last Touch Model)
+SELECT
+ ad_campaign_name,
+ SUM(ad_spend) as total_spend,
+ SUM(sm_last_touch_revenue) as attributed_revenue,
+ SAFE_DIVIDE(SUM(sm_last_touch_revenue), SUM(ad_spend)) as roas
+FROM `your_project.sm_experimental.rpt_ad_attribution_performance_daily`
+WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+ AND ad_id IS NOT NULL
+GROUP BY 1
+ORDER BY 4 DESC
+```
+
+## Supporting Models
+
+### Outbound Message Performance Daily (`rpt_outbound_message_performance_daily`)
+
+This model provides daily performance metrics for email and SMS campaigns, which can be connected to the Email/SMS dimension in the attribution models.
+
+#### Key Columns
+
+- **Identifiers**
+ - `sm_store_id`: SourceMedium store identifier (brand/workspace; formerly `smcid`)
+ - `date`: Performance date
+ - `sm_message_channel`: Channel (email or SMS)
+ - `message_id`: Unique identifier for the message
+ - `campaign_id`: Campaign identifier
+
+- **Message Metadata**
+ - `message_name`: Name of the message
+ - `message_subject`: Subject line of the message
+ - `campaign_name`: Name of the campaign
+
+- **Performance Metrics**
+ - `message_unique_sends`: Number of unique sends
+ - `message_unique_receives`: Number of unique receives
+ - `message_unique_opens`: Number of unique opens
+ - `message_unique_clicks`: Number of unique clicks
+ - `message_unique_bounces`: Number of unique bounces
+ - `platform_reported_orders`: Number of orders reported by the platform
+ - `platform_reported_order_revenue`: Revenue reported by the platform
+
+#### Usage with Attribution
+
+This model is particularly useful when analyzing the Email/SMS dimension in the MTA system, as it provides engagement metrics for the messages that appear in attribution reports.
+
+```sql
+-- Email campaign performance with attribution
+SELECT
+ r.campaign_name,
+ r.message_name,
+ SUM(r.message_unique_receives) as deliveries,
+ SUM(r.message_unique_opens) as opens,
+ SUM(r.message_unique_clicks) as clicks,
+ SUM(a.last_touch_revenue) as last_touch_revenue
+FROM `your_project.sm_transformed_v2.rpt_outbound_message_performance_daily` r
+LEFT JOIN (
+ SELECT
+ dimension_value.email_sms as message_id,
+ SUM(last_touch_revenue_impact.email_sms) as last_touch_revenue
+ FROM `your_project.sm_experimental.obt_purchase_journeys_with_mta_models`
+ WHERE
+ sm_store_id = 'your-sm_store_id'
+ AND sm_event_name = 'purchase'
+ AND last_touch_revenue_impact.email_sms > 0
+ GROUP BY 1
+) a ON r.message_id = a.message_id
+WHERE
+ r.sm_store_id = 'your-sm_store_id'
+ AND r.date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) AND CURRENT_DATE()
+GROUP BY 1, 2
+ORDER BY 6 DESC
+```
+
+### Funnel Event History (`obt_funnel_event_history`)
+
+This model contains the raw event data that forms the basis of the attribution system, collecting and standardizing events from various sources.
+
+#### Key Features
+
+- Comprehensive collection of customer events across the purchase funnel
+- Standardized event schema following GA4 conventions
+- Deduplication of events across multiple sources
+- Extraction and normalization of UTM parameters and other identifiers
+
+While most users will interact with the attribution models rather than this raw event data, understanding its existence helps provide context for how the attribution system works. This model captures the individual interactions that make up customer journeys.
+
+## BigQuery Access and Customization
+
+All these models are available in your managed BigQuery instance, allowing you to:
+
+1. Build custom reports and visualizations
+2. Join attribution data with other business data
+3. Create advanced segmentation analyses
+4. Develop customer-specific attribution rules
+
+If you need assistance accessing these models or building custom queries, contact your SourceMedium account manager.
diff --git a/mta/mta-overview.mdx b/mta/mta-overview.mdx
index b9d56a3..028677d 100644
--- a/mta/mta-overview.mdx
+++ b/mta/mta-overview.mdx
@@ -1,23 +1,23 @@
---
-title: "Source Medium Multi-Touch Attribution Overview"
+title: "SourceMedium Multi-Touch Attribution Overview"
sidebarTitle: "MTA Overview"
-description: "Learn the basics of Source Medium Multi-Touch Attribution"
+description: "Learn the basics of SourceMedium Multi-Touch Attribution"
icon: "sitemap"
iconType: "solid"
---
-### What is Source Medium Multi-Touch Attribution (MTA)?
+### What is SourceMedium Multi-Touch Attribution (MTA)?
Our model provides a comprehensive view of how various marketing efforts contribute to customer purchases.
By unifying data from multiple sources of first party data you already own, we construct detailed purchase journeys that help you understand the impact of different marketing channels, landing pages, and ad creatives.
-In the sections below, this document will provide everything you need to know to get started with Source Medium
+In the sections below, this document will provide everything you need to know to get started with SourceMedium
MTA.
If you have a specific question and you’d like to skip the overview guide, check out our [MTA FAQs](/mta/mta-faqs) or use the AI-enabled search bar above to
quickly find what you’re looking for.
-If you’re already familiar with Source Medium MTA data and you’d like to explore how to use our built-in reporting, skip ahead to Section 3.
+If you’re already familiar with SourceMedium MTA data and you’d like to explore how to use our built-in reporting, skip ahead to Section 3.
For a verbose technical explanation, skip ahead to our [MTA Advanced Documentation](/mta/mta-advanced-documentation).
@@ -30,21 +30,21 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
- A **touch point** is an event, occurring before a purchase, where an interaction with a customer is made and touch point data is captured
- **Touch point data** must contain at least one of the following to be considered valid: a landing page, an ad creative, or a marketing channel (mapped UTM data)
- - Add to carts, purchases, and confirmations are touch points, but they are not the primary focus of the Source Medium MTA model as they do not provide attribution insights
+ - Add to carts, purchases, and confirmations are touch points, but they are not the primary focus of the SourceMedium MTA model as they do not provide attribution insights
- Touch points are only valid within the **lookback window**, which is 120 days before the customer makes their purchase
- A **purchase journey** includes all recorded touch points leading up to a purchase made by a customer, an example is displayed in the figure below
- - Source Medium MTA standardizes purchase journeys to the [GA4 E-Commerce Event Schema](https://support.google.com/analytics/answer/9267735?hl=en) that you may already be familiar with
- - There are often many data sources reporting many purchase journeys for each purchase, Source Medium MTA selects the highest quality purchase journey available by number of valid touch points—read more on this in the modeling section below
+ - SourceMedium MTA standardizes purchase journeys to the [GA4 E-Commerce Event Schema](https://support.google.com/analytics/answer/9267735?hl=en) that you may already be familiar with
+ - There are often many data sources reporting many purchase journeys for each purchase, SourceMedium MTA selects the highest quality purchase journey available by number of valid touch points—read more on this in the modeling section below
- With the best purchase journey selected for each customer purchase, the collection of these journeys tells a detailed story of how marketing efforts bring in business
- - You can interact with the Source Medium MTA dataset through pre-built analysis modules and even by building your own charts or BI solutions directly on top of the modeled dataset—read more on this in the reporting section below
+ - You can interact with the SourceMedium MTA dataset through pre-built analysis modules and even by building your own charts or BI solutions directly on top of the modeled dataset—read more on this in the reporting section below
@@ -54,20 +54,20 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
- Source Medium MTA takes multiple data sources reporting many customer journeys, unifies them into a single schema and assesses their quality, then combines the best of those purchase journeys with Marketing Data, Orders Data, Customer Data, and User Inputs to create a Unified Purchase Journey Dataset. View this process in the figure below.
+ SourceMedium MTA takes multiple data sources reporting many customer journeys, unifies them into a single schema and assesses their quality, then combines the best of those purchase journeys with Marketing Data, Orders Data, Customer Data, and User Inputs to create a Unified Purchase Journey Dataset. View this process in the figure below.
- 1. Source Medium integrates first-party purchase funnel data from a variety of **data sources**, you’ll see them listed and categorized on the left-hand side of the chart above
+ 1. SourceMedium integrates first-party purchase funnel data from a variety of **data sources**, you’ll see them listed and categorized on the left-hand side of the chart above
2. The purchase journeys from all data sources are assessed for quality by number of valid touch points and the best are selected, this creates the **Unified Event Schema** you’ll see in the middle of the chart
3. The Unified event Schema is combined with Marketing Data, Orders Data, Customer Data, and User Inputs using the appropriate identifier matching for each to create a set of **Unified Purchase Journeys** which you’ll see on the right-hand side of the chart
- Source Medium models attribution in three key ways:
+ SourceMedium models attribution in three key ways:
1. **First Touch Attribution:**
- Assigns all credit to the first valid touch point in the purchase journey
- Ideal for understanding initial customer acquisition channels
@@ -75,8 +75,13 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
- Assigns all credit to the last valid touch point before the purchase
- Useful for identifying conversion-driving channels
3. **Linear Attribution**
- - Distributes credit equally among all valid touch points
- - Provides a balanced and complete view across the entire purchase journey
+ - Distributes credit equally among all **unique** valid touch points
+ - Uses session-based deduplication to avoid over-crediting repeated interactions
+ - Provides a balanced view of distinct marketing contributions
+
+
+ **Example**: If a customer clicks the same Facebook ad 3 times in one browsing session, linear attribution counts this as 1 unique touchpoint, not 3. This prevents inflating the importance of repetitive interactions.
+
@@ -85,17 +90,17 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
-
- Source Medium MTA data architecture and modeling powers a robust suite of detailed reports to help you analyze and optimize your marketing efforts. If desired, you can customize these MTA reports for your use case—and you can even build custom BI solutions or train machine learning models directly on top of the Unified Purchase Journey MTA data from your managed data warehouse.
+
+ SourceMedium MTA data architecture and modeling powers a robust suite of detailed reports to help you analyze and optimize your marketing efforts. If desired, you can customize these MTA reports for your use case—and you can even build custom BI solutions or train machine learning models directly on top of the Unified Purchase Journey MTA data from your managed data warehouse.
- If you're already familiar with Source Medium MTA, or you'd like to just get started with analysis, feel free to skip the Reporting Definitions below and move ahead to the MTA Built-in Reports section.
+ If you're already familiar with SourceMedium MTA, or you'd like to just get started with analysis, feel free to skip the Reporting Definitions below and move ahead to the MTA Built-in Reports section.
**Model Dimension**
- - In the specific case of Source Medium MTA, model dimension refers to the type of touch point being analyzed
- - There are 3 model dimension types used in Source Medium MTA:
+ - In the specific case of SourceMedium MTA, model dimension refers to the type of touch point being analyzed
+ - There are 3 model dimension types used in SourceMedium MTA:
- **Marketing Channels (mapped UTM)**
- **Ads**
- **Landing Pages**
@@ -120,7 +125,7 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
_Example:_ A **Minimum Distinct Dimension Values** setting of 3 for the Landing Pages model dimension will filter out all purchase journeys with less than 3 distinct landing pages recorded
**Attribution Type**
- - Source Medium MTA modeling enables three different attribution types:
+ - SourceMedium MTA modeling enables three different attribution types:
- **First Touch:** Assigns all credit to the first valid touch point in the purchase journey
- **Last Touch:** Assigns all credit to the last valid touch point before the purchase
- **Linear:** Distributes credit equally among all valid touch points
@@ -140,21 +145,21 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
_Examples:_ Google Analytics, Elevar, and Blotout are **Source Systems** used by Source medium MTA
-
- Source Medium MTA built-in reports are part of a standalone dashboard separate from your main Source Medium dash. After MTA is enabled for your account, the dashboard link will be pinned to your shared Slack channel or sent via email/gchat if you do not use Slack. The sections below describe each of the default modules and their functionality.
+
+ SourceMedium MTA built-in reports are part of a standalone dashboard separate from your main SourceMedium dash. After MTA is enabled for your account, the dashboard link will be pinned to your shared Slack channel or sent via email/gchat if you do not use Slack. The sections below describe each of the default modules and their functionality.
- This module provides an overview of how complete your business data is for use with Source Medium MTA. If you find your attribution rates to be low, the [MTA Advanced Documentation](/mta/mta-advanced-documentation) provides common solutions to this problem in the Attribution Improvement section. You’ll also find a video overview at the top of this module if you’d prefer watching a guide instead of the written format shown here.
+ This module provides an overview of how complete your business data is for use with SourceMedium MTA. If you find your attribution rates to be low, the [MTA Advanced Documentation](/mta/mta-advanced-documentation) provides common solutions to this problem in the Attribution Improvement section. You’ll also find a video overview at the top of this module if you’d prefer watching a guide instead of the written format shown here.
- _User Interactions:_
Select a **date range** to display data from—complete purchase journeys will be included if their associated purchase date is within the date range, touch points are not excluded by the date setting
_This filter is present on all Source Medium MTA modules_
+ _User Interactions:_
Select a **date range** to display data from—complete purchase journeys will be included if their associated purchase date is within the date range, touch points are not excluded by the date setting
_This filter is present on all SourceMedium MTA modules_
- This module is the heart of Source Medium MTA reporting. Here you’ll find aggregates of all your MTA data for each of the three attribution types, across all three model dimensions.
+ This module is the heart of SourceMedium MTA reporting. Here you’ll find aggregates of all your MTA data for each of the three attribution types, across all three model dimensions.
_User Interactions:_
Choose a **Model Dimension** to select the type of touch points you’d like to analyze
Set the **Minimum Dimension Values** to filter the number of touch points per purchase journey
Choose **Dimension Value(s)** to select which specific Marketing Channels, Ads, or Landing Pages you’d like to analyze touch points from
Select the **first and/or last touch dimension value** to set a specific beginning and/or end to the customer journeys you are analyzing
@@ -181,8 +186,8 @@ For a verbose technical explanation, skip ahead to our [MTA Advanced Documentati
-
- To customize the Source Medium MTA dashboard, such as changing visualizations or swapping metrics, you can use the edit mode in Looker Studio as you would on your main dashboard. For more information on how to do this, see our Looker Studio Customization Guide (in progress, link coming).
+
+ To customize the SourceMedium MTA dashboard, such as changing visualizations or swapping metrics, you can use the edit mode in Looker Studio as you would on your main dashboard. For more information on how to do this, see our Looker Studio Customization Guide (in progress, link coming).
To access the MTA data directly within your managed data warehouse for custom BI solutions or ML modeling, or for more advanced usage and customization information, view the Warehouse Data section of our [MTA Advanced Documentation](/mta/mta-advanced-documentation).
diff --git a/onboarding/analytics-tools/bigquery-essentials.mdx b/onboarding/analytics-tools/bigquery-essentials.mdx
new file mode 100644
index 0000000..f1a327b
--- /dev/null
+++ b/onboarding/analytics-tools/bigquery-essentials.mdx
@@ -0,0 +1,365 @@
+---
+title: "BigQuery Essentials for SourceMedium"
+sidebarTitle: "BigQuery Essentials"
+description: "Practical SQL queries for analyzing your SourceMedium data in BigQuery"
+icon: "database"
+---
+
+## Overview
+
+BigQuery is Google's fully-managed, serverless data warehouse where your SourceMedium data lives. It excels at large-scale data analysis, handling complex data types, and provides granular access control through IAM integration.
+
+This guide provides practical queries you can run immediately against your `sm_transformed_v2` dataset.
+
+
+**Dataset location**: All SourceMedium tables are in the `sm_transformed_v2` dataset within your Google Cloud project.
+
+
+
+**New to BigQuery?** Start with [Google's How to Get Started with BigQuery video](https://www.youtube.com/watch?v=BH_7_zVk5oM&t=2s) for a quick introduction.
+
+
+---
+
+## Essential Queries
+
+### 1. Daily Revenue Summary
+
+```sql
+select
+ date(order_processed_at_local_datetime) as order_date,
+ count(distinct sm_order_key) as orders,
+ count(distinct sm_customer_key) as customers,
+ sum(order_gross_revenue) as gross_revenue,
+ sum(order_total_discounts) as discounts,
+ sum(order_net_revenue) as net_revenue
+from `your_project.sm_transformed_v2.obt_orders`
+where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+group by 1
+order by 1 desc
+```
+
+
+**Always filter with `is_order_sm_valid = true`** to exclude test orders, cancelled orders, and other invalid transactions.
+
+
+### 2. Channel Performance
+
+```sql
+select
+ sm_channel,
+ count(distinct sm_order_key) as orders,
+ sum(order_net_revenue) as revenue,
+ round(sum(order_net_revenue) / count(distinct sm_order_key), 2) as aov
+from `your_project.sm_transformed_v2.obt_orders`
+where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+group by 1
+order by revenue desc
+```
+
+### 3. New vs Returning Customers
+
+```sql
+select
+ date(order_processed_at_local_datetime) as order_date,
+ order_sequence as customer_type,
+ count(distinct sm_order_key) as orders,
+ count(distinct sm_customer_key) as customers,
+ sum(order_net_revenue) as revenue
+from `your_project.sm_transformed_v2.obt_orders`
+where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+group by 1, 2
+order by 1 desc, 2
+```
+
+### 4. Top Products by Revenue
+
+```sql
+select
+ product_title,
+ sum(order_line_quantity) as units_sold,
+ count(distinct sm_order_key) as orders,
+ sum(order_line_net_revenue) as revenue
+from `your_project.sm_transformed_v2.obt_order_lines`
+where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+group by 1
+order by revenue desc
+limit 20
+```
+
+### 5. Attribution by Source/Medium
+
+```sql
+select
+ coalesce(sm_utm_source, '(direct)') as source,
+ coalesce(sm_utm_medium, '(none)') as medium,
+ count(distinct sm_order_key) as orders,
+ sum(order_net_revenue) as revenue
+from `your_project.sm_transformed_v2.obt_orders`
+where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+group by 1, 2
+order by revenue desc
+limit 20
+```
+
+### 6. Marketing Spend vs Revenue by Channel
+
+```sql
+with daily_spend as (
+ select
+ date as report_date,
+ sm_channel,
+ sum(ad_spend) as spend,
+ sum(ad_impressions) as impressions,
+ sum(ad_clicks) as clicks
+ from `your_project.sm_transformed_v2.rpt_ad_performance_daily`
+ where date >= date_sub(current_date(), interval 30 day)
+ group by 1, 2
+),
+daily_revenue as (
+ select
+ date(order_processed_at_local_datetime) as order_date,
+ sm_channel,
+ sum(order_net_revenue) as revenue,
+ count(distinct sm_order_key) as orders
+ from `your_project.sm_transformed_v2.obt_orders`
+ where is_order_sm_valid = true
+ and date(order_processed_at_local_datetime) >= date_sub(current_date(), interval 30 day)
+ group by 1, 2
+)
+select
+ coalesce(s.report_date, r.order_date) as date,
+ coalesce(s.sm_channel, r.sm_channel) as channel,
+ s.spend,
+ r.revenue,
+ r.orders,
+ round(safe_divide(r.revenue, s.spend), 2) as roas
+from daily_spend s
+full outer join daily_revenue r
+ on s.report_date = r.order_date
+ and s.sm_channel = r.sm_channel
+order by 1 desc, 2
+```
+
+---
+
+## Key Tables Reference
+
+| Table | Description | Key Columns |
+|-------|-------------|-------------|
+| `obt_orders` | One row per order | `sm_order_key`, `order_net_revenue`, `sm_channel` |
+| `obt_order_lines` | One row per line item | `sm_order_line_key`, `product_title`, `order_line_quantity` |
+| `obt_customers` | One row per customer | `sm_customer_key`, `customer_email`, `source_system` |
+| `rpt_ad_performance_daily` | Daily ad metrics by ad | `date`, `sm_channel`, `ad_spend`, `ad_impressions` |
+
+For complete table documentation, see the [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2/index).
+
+---
+
+## Important Filters
+
+### Valid Orders Only
+Always include `is_order_sm_valid = true` to exclude:
+- Test orders
+- Cancelled orders
+- Fully refunded orders
+- Draft orders
+
+### Date Ranges
+Use `date_sub(current_date(), interval N day)` for rolling windows:
+- Last 7 days: `interval 7 day`
+- Last 30 days: `interval 30 day`
+- Last 90 days: `interval 90 day`
+
+### Primary Date Field
+Use `order_processed_at_local_datetime` as the primary date field for order analytics. This is the order processed timestamp converted to your reporting timezone.
+
+---
+
+## Permissions & Sharing
+
+BigQuery integrates with Identity and Access Management (IAM) to provide granular control over who has access to your data. You can assign specific roles to users and control their permissions on a project-wide or dataset-wide level.
+
+
+
+ The `SM Managed WH - Admin` user role (the default role all Managed Data Warehouse customers receive) includes the following permissions:
+
+ ```
+ bigquery.config.get
+ bigquery.dataPolicies.create
+ bigquery.dataPolicies.delete
+ bigquery.dataPolicies.get
+ bigquery.dataPolicies.getIamPolicy
+ bigquery.dataPolicies.list
+ bigquery.dataPolicies.setIamPolicy
+ bigquery.dataPolicies.update
+ bigquery.datasets.create
+ bigquery.datasets.createTagBinding
+ bigquery.datasets.delete
+ bigquery.datasets.deleteTagBinding
+ bigquery.datasets.get
+ bigquery.datasets.getIamPolicy
+ bigquery.datasets.link
+ bigquery.datasets.listEffectiveTags
+ bigquery.datasets.listSharedDatasetUsage
+ bigquery.datasets.listTagBindings
+ bigquery.datasets.setIamPolicy
+ bigquery.datasets.update
+ bigquery.datasets.updateTag
+ bigquery.jobs.create
+ bigquery.jobs.list
+ bigquery.models.create
+ bigquery.models.delete
+ bigquery.models.export
+ bigquery.models.getData
+ bigquery.models.getMetadata
+ bigquery.models.list
+ bigquery.models.updateData
+ bigquery.models.updateMetadata
+ bigquery.models.updateTag
+ bigquery.readsessions.create
+ bigquery.readsessions.getData
+ bigquery.readsessions.update
+ bigquery.routines.create
+ bigquery.routines.delete
+ bigquery.routines.get
+ bigquery.routines.list
+ bigquery.routines.update
+ bigquery.routines.updateTag
+ bigquery.rowAccessPolicies.create
+ bigquery.rowAccessPolicies.delete
+ bigquery.rowAccessPolicies.getIamPolicy
+ bigquery.rowAccessPolicies.list
+ bigquery.rowAccessPolicies.setIamPolicy
+ bigquery.rowAccessPolicies.update
+ bigquery.tables.create
+ bigquery.tables.createIndex
+ bigquery.tables.createSnapshot
+ bigquery.tables.delete
+ bigquery.tables.deleteIndex
+ bigquery.tables.deleteSnapshot
+ bigquery.tables.export
+ bigquery.tables.get
+ bigquery.tables.getData
+ bigquery.tables.getIamPolicy
+ bigquery.tables.list
+ bigquery.tables.replicateData
+ bigquery.tables.restoreSnapshot
+ bigquery.tables.setCategory
+ bigquery.tables.setIamPolicy
+ bigquery.tables.update
+ bigquery.tables.updateData
+ bigquery.tables.updateTag
+ bigquery.transfers.get
+ bigquery.transfers.update
+ iam.serviceAccountKeys.create
+ iam.serviceAccountKeys.delete
+ iam.serviceAccountKeys.disable
+ iam.serviceAccountKeys.enable
+ iam.serviceAccountKeys.get
+ iam.serviceAccountKeys.list
+ iam.serviceAccounts.create
+ iam.serviceAccounts.delete
+ iam.serviceAccounts.disable
+ iam.serviceAccounts.enable
+ iam.serviceAccounts.get
+ iam.serviceAccounts.getIamPolicy
+ iam.serviceAccounts.list
+ iam.serviceAccounts.setIamPolicy
+ iam.serviceAccounts.undelete
+ iam.serviceAccounts.update
+ resourcemanager.folders.get
+ resourcemanager.folders.getIamPolicy
+ resourcemanager.folders.setIamPolicy
+ resourcemanager.projects.get
+ resourcemanager.projects.getIamPolicy
+ resourcemanager.projects.list
+ resourcemanager.projects.setIamPolicy
+ ```
+
+ For more details, see [IAM Permissions Documentation](https://cloud.google.com/bigquery/docs/access-control).
+
+
+ Use [Google Groups](/onboarding/analytics-tools/google-groups-access-control) to manage BigQuery access efficiently:
+
+ 1. Create a Google Group for your analytics team
+ 2. Grant the group BigQuery Data Viewer or Editor role
+ 3. Add team members to the group as needed
+
+ See [Control Access to Resources with IAM](https://cloud.google.com/bigquery/docs/control-access-to-resources-iam) for detailed instructions.
+
+
+ For Looker Studio data sources, we recommend using a service account as the Data Credential:
+
+ - Ensures consistent access regardless of who created the data source
+ - Simplifies permission management
+ - Avoids issues when employees leave
+
+ See [Provisioning Service Accounts](https://cloud.google.com/iam/docs/service-account-overview) for setup instructions.
+
+
+
+---
+
+## Computing Power & Workload
+
+BigQuery uses a reservation model with "slots" representing computational capacity for running queries.
+
+
+**SourceMedium Managed Data Warehouse customers** receive up to 100 slot-hours to use at their discretion. Most businesses never reach this quota with normal analytical usage.
+
+
+For more details on managing compute resources, see the [Workload Management Documentation](https://cloud.google.com/bigquery/docs/reservations-intro).
+
+---
+
+## BigQuery Tips
+
+
+
+ Click **Preview** on any table to see sample data without running a query (free).
+
+
+ BigQuery shows estimated data scanned in the top right corner of the query editor. This determines cost—always check before running large queries.
+
+
+ Add `LIMIT 100` while building queries to reduce costs and speed up iteration.
+
+
+ Use **Save Query** to store queries you run often. Organize with folders for easy access.
+
+
+ BigQuery supports arrays and structs (nested data). Use `UNNEST()` to flatten arrays for analysis. See [Google BigQuery Data Types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types) for details.
+
+
+
+---
+
+## Getting Help
+
+- **Query errors**: Check column names against the [table documentation](/data-activation/data-tables/sm_transformed_v2/index)
+- **Permission issues**: See [Google Groups Access Control](/onboarding/analytics-tools/google-groups-access-control)
+- **Data questions**: Contact your SourceMedium support team
+
+---
+
+## Additional Resources
+
+**Google Documentation:**
+- [GoogleSQL Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql)
+- [Query Syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax)
+- [Creating and Using Tables](https://cloud.google.com/bigquery/docs/tables)
+- [Introduction to Views](https://cloud.google.com/bigquery/docs/views-intro)
+- [Loading Data](https://cloud.google.com/bigquery/docs/loading-data)
+- [BigQuery Pricing](https://cloud.google.com/bigquery/pricing)
+
+**SourceMedium Resources:**
+- [SQL Query Library](/data-activation/template-resources/sql-query-library) — Copy-paste SQL templates for common analyses
+- [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2/index)
+- [Looker Studio Guide](/onboarding/analytics-tools/looker-studio-guide)
+- [Google Groups Access Control](/onboarding/analytics-tools/google-groups-access-control)
diff --git a/onboarding/analytics-tools/connect-bigquery-to-looker-studio.mdx b/onboarding/analytics-tools/connect-bigquery-to-looker-studio.mdx
new file mode 100644
index 0000000..3d65e0e
--- /dev/null
+++ b/onboarding/analytics-tools/connect-bigquery-to-looker-studio.mdx
@@ -0,0 +1,58 @@
+---
+title: "Connect BigQuery to Looker Studio"
+sidebarTitle: "Connect BigQuery → Looker Studio"
+description: "Use any BigQuery table (including SourceMedium tables) as a Looker Studio data source."
+icon: "link"
+---
+
+## TL;DR
+
+- You can connect **any** BigQuery table or view (including `sm_transformed_v2` tables) to Looker Studio using the **BigQuery connector**.
+- If you start from a SourceMedium Looker Studio template, it’s usually **already connected** to your BigQuery project—adding more data is just adding another **data source**.
+- If you don’t see data, it’s almost always a **permissions** or **credentials mode** issue.
+
+---
+
+## Connect a BigQuery table (fast)
+
+
+
+ In Looker Studio, open your report and click **Edit**.
+
+
+ Go to **Resource → Manage added data sources → Add a data source**, then choose **BigQuery**.
+
+
+ Select your Google Cloud project, dataset (commonly `sm_transformed_v2`), and the table you want (for example, `obt_orders`), then click **Add**.
+
+
+
+
+If you’re new to Looker Studio data sources, the [Looker Studio Guide](/onboarding/analytics-tools/looker-studio-guide) explains connectors, data sources, and credential modes.
+
+
+---
+
+## Add more tables to an existing SourceMedium template
+
+When you copy a SourceMedium template, the existing charts are already wired to existing data sources. To use additional tables:
+
+- Create a **new data source** pointing at the table/view you want in BigQuery
+- Update a chart to use it: select the chart → **Data** panel → **Data source** → choose your new data source
+
+---
+
+## Common gotchas
+
+
+
+ Make sure you’re signed into the **same Google account** that has access to your BigQuery project, and that you have permission to view datasets and tables.
+
+
+ Check the data source credential mode (Owner vs Viewer). SourceMedium dashboards typically work best with **Owner’s credentials** so viewers don’t need direct BigQuery access.
+
+
+
+
+Google's official walkthrough: [BigQuery + Looker Studio](https://docs.cloud.google.com/bigquery/docs/visualize-looker-studio)
+
diff --git a/onboarding/analytics-tools/connect-to-other-bi-tools.mdx b/onboarding/analytics-tools/connect-to-other-bi-tools.mdx
new file mode 100644
index 0000000..3df8718
--- /dev/null
+++ b/onboarding/analytics-tools/connect-to-other-bi-tools.mdx
@@ -0,0 +1,29 @@
+---
+title: "Use SourceMedium data in other BI tools"
+sidebarTitle: "Other BI tools"
+description: "Your SourceMedium data lives in BigQuery, so you can connect it to Tableau, Looker, and other BI tools."
+icon: "chart-bar"
+---
+
+## TL;DR
+
+- SourceMedium data lives in **BigQuery**, so you can use it in **any BI tool that can connect to BigQuery**.
+- You’ll typically select your **Google Cloud project** → dataset (commonly `sm_transformed_v2`) → table/view (or use a **custom SQL query**).
+- Make sure the user or service account you connect with has the right **BigQuery permissions** for the project/dataset.
+
+---
+
+## Recommended Google docs (best starting points)
+
+- [BigQuery data analysis tools overview](https://docs.cloud.google.com/bigquery/docs/data-analysis-tools-intro)
+- [Tableau + BigQuery](https://docs.cloud.google.com/bigquery/docs/analyze-data-tableau)
+- [Looker + BigQuery](https://docs.cloud.google.com/bigquery/docs/looker)
+- [Looker Studio + BigQuery](https://docs.cloud.google.com/bigquery/docs/visualize-looker-studio)
+- [Third-party integrations](https://docs.cloud.google.com/bigquery/docs/third-party-integration)
+
+---
+
+## Notes for SourceMedium customers
+
+- For Looker Studio specifically, see [Connect BigQuery to Looker Studio](/onboarding/analytics-tools/connect-bigquery-to-looker-studio).
+- If you’re building dashboards for a team, prefer connecting with a **service account** (or a shared/managed identity) so access doesn’t break when an employee leaves.
diff --git a/onboarding/analytics-tools/creating-google-groups.mdx b/onboarding/analytics-tools/creating-google-groups.mdx
deleted file mode 100644
index 6ceed8f..0000000
--- a/onboarding/analytics-tools/creating-google-groups.mdx
+++ /dev/null
@@ -1,95 +0,0 @@
----
-title: 'Creating and Maintaining Google Groups'
-sidebarTitle: 'Managing Google Groups'
-description: ""
----
-
-Google Groups makes it easy to manage data source and dashboard access for big teams by keeping everything in one place!
-
-We recommend setting up Google Groups for your different user types based on the access they should have to certain resources.
-
-
-### Step 1: Sign in to Google Groups
-- Go to [Google Groups](https://groups.google.com).
-- Sign in using your Google account.
-
-### Step 2: Create a New Group
-- Click on the **Create Group** button.
-- Fill in the necessary details:
- - **Group Name**: Enter a name that represents the group's purpose.
- - **Group Email Address**: Choose a unique email address for the group (e.g., `company_name_sourcemedium@googlegroups.com`).
- - **Group Description**: Provide a brief description of the group’s purpose.
-
-### Step 3: Set Group Permissions
-- Choose the appropriate settings for who can:
- - View the group.
- - Join the group.
- - Post to the group.
- - View member details.
-- Decide whether new members require approval or if they can join automatically.
-- Configure any additional group settings, such as moderation or message posting policies.
-
-### Step 4: Finalize and Create
-- Review the settings to ensure they align with your needs.
-- Click **Create** to finish setting up the group.
-
----
-
-## Adding and Managing Members
-
-### Step 1: Add Members to the Group
-
-- Go to your group in Google Groups.
-- Click on **Manage** on the left panel.
-- Under **Members**, click **Direct Add Members**.
-- Enter the email addresses of the members you want to add.
-- Optionally, customize the welcome message and set the default email preferences for new members.
-- Click **Add**.
-
-### Step 2: Manage Member Roles and Permissions
-
-- In the **Manage** section, go to **Members**.
-- Select the member whose role you want to change.
-- Choose the desired role (e.g., Owner, Manager, or Member).
-- Update roles as needed based on group requirements.
-
-### Step 3: Remove Members from the Group
-
-- Navigate to the **Members** section under **Manage**.
-- Select the member(s) you wish to remove.
-- Click **Remove** and confirm.
-
----
-
-## Configuring and Managing Group Settings
-
-### Step 1: Access Group Settings
-
-- Open your group in Google Groups.
-- Click **Manage**.
-- Under the **Settings** section, choose **Group Settings**.
-
-### Step 2: Update General Information
-
-- Modify the group name, description, or email address as needed.
-- Adjust visibility and access settings based on group requirements.
-
----
-
-## Maintaining the Google Group
-
-### Step 1: Regularly Review Group Membership
-
-- Periodically check group members to ensure they are up to date.
-- Remove inactive members or those no longer relevant to the group’s purpose.
-
-### Step 2: Update Group Settings as Needed
-
-- Modify settings periodically to accommodate changes in the group’s membership or organizational policies.
-
----
-
-## Group Troubleshooting and Support
-
-- **Access Help Center**: Visit the [Google Groups Help Center](https://support.google.com/groups/) for troubleshooting common issues.
-- **Contact Support**: If needed, reach out to Google Workspace support for more complex issues.
diff --git a/onboarding/analytics-tools/google-groups-access-control.mdx b/onboarding/analytics-tools/google-groups-access-control.mdx
new file mode 100644
index 0000000..a6b017e
--- /dev/null
+++ b/onboarding/analytics-tools/google-groups-access-control.mdx
@@ -0,0 +1,150 @@
+---
+title: "Google Groups for Access Control"
+sidebarTitle: "Google Groups Access Control"
+description: "Use Google Groups as a single identity to manage access across Looker Studio dashboards, BigQuery, and Google Sheets"
+icon: "users"
+---
+
+## Why Google Groups?
+
+Google Groups acts as an **identity primitive** across Google's ecosystem. One group email grants access to:
+
+- **Looker Studio dashboards** (viewer or editor)
+- **BigQuery datasets** (query access)
+- **Google Sheets** (config sheets, exports)
+
+
+**One group email = unified access control.** Add a teammate to the group once, and they automatically get access to all shared resources.
+
+
+---
+
+## Quick Start: Create a Group
+
+
+
+ Navigate to [groups.google.com](https://groups.google.com) and sign in with your organization account.
+
+
+ 
+
+
+ - **Group name**: Descriptive name (e.g., "Acme Analytics Team")
+ - **Group email**: `acme-analytics@googlegroups.com`
+ - **Description**: Who should be in this group and what they access
+
+ 
+
+
+ Choose who can find and join the group. For internal teams, "Only invited users" is recommended.
+
+ 
+
+
+ Enter email addresses for initial members, then click **Create group**.
+
+ 
+
+
+
+---
+
+## Managing Group Members
+
+### Add members
+Click **Add Members** at the top of your group page.
+
+
+
+### Adjust permissions
+Go to **Group Settings** to modify who can post, view members, or join.
+
+
+
+### Allow external members
+If you need to add people outside your organization, enable this in Group Settings:
+
+
+
+---
+
+## Sharing Resources with Your Group
+
+Once your group exists, use the group email to grant access across Google products.
+
+### Looker Studio Dashboards
+
+1. Open your dashboard and click **Share** (top right)
+2. Enter the group email address
+3. Choose permission level:
+ - **Viewer**: Can view and interact with filters
+ - **Editor**: Can modify the dashboard
+
+
+
+
+**Recommendation**: Grant **Viewer** access to most users. Editor access can lead to accidental changes that break dashboards.
+
+
+### Google Sheets (Config Sheets)
+
+1. Open the sheet and click **Share**
+2. Enter the group email
+3. Choose permission level:
+ - **Viewer**: Read-only
+ - **Commenter**: Can add comments
+ - **Editor**: Can modify content
+
+
+
+### BigQuery Datasets
+
+For BigQuery access, your SourceMedium team will configure IAM permissions using your group email. Contact support if you need to grant BigQuery access to additional team members.
+
+---
+
+## Recommended Group Structure
+
+For most teams, we recommend two groups:
+
+| Group | Purpose | Typical Access |
+|-------|---------|----------------|
+| `company-sm-viewers` | Day-to-day dashboard users | Dashboard: Viewer, Sheets: Viewer |
+| `company-sm-admins` | Analytics leads, data team | Dashboard: Editor, Sheets: Editor, BigQuery: Query |
+
+
+Start with one group for simplicity. Split into viewer/admin groups when you have 5+ users with different needs.
+
+
+---
+
+## Troubleshooting
+
+### "You don't have access" error
+
+
+
+ Verify the user is actually in the group at [groups.google.com](https://groups.google.com).
+
+
+ Permission changes can take time to propagate across Google services. If you just added someone to the group or shared a resource, have the user sign out and back in, then try again.
+
+
+ Ensure the resource was shared with the **group email** (e.g., `team@googlegroups.com`), not an individual.
+
+
+ If adding external users, ensure "Allow members outside your organization" is enabled in Group Settings.
+
+
+
+### Dashboard shows "No data"
+
+This usually means the **data source** permissions are separate from dashboard permissions. Contact SourceMedium support to verify data source access.
+
+---
+
+## Related Resources
+
+- [Google Groups Help Center](https://support.google.com/groups/)
+- [Looker Studio sharing documentation](https://support.google.com/looker-studio/answer/10403868)
+- [BigQuery IAM overview](https://cloud.google.com/bigquery/docs/access-control)
diff --git a/onboarding/analytics-tools/learn-bigquery.mdx b/onboarding/analytics-tools/learn-bigquery.mdx
deleted file mode 100644
index 48fb013..0000000
--- a/onboarding/analytics-tools/learn-bigquery.mdx
+++ /dev/null
@@ -1,137 +0,0 @@
----
-title: "Learn BigQuery"
-description: "Use Cases & Important Information"
----
-### Overview
-
-BigQuery is a powerful tool for large-scale data analysis, handling complex data types, managing permissions and sharing, and controlling computing power and workload. It can process massive datasets quickly, handle a variety of data types, and allows granular control over data access with IAM integration.
-
-A great place to start is with [Google's How to Get Started with BigQuery video](https://www.youtube.com/watch?v=BH_7_zVk5oM&t=2s).
-
-### **Large-Scale Data Analysis**
-
-BigQuery excels in analyzing massive datasets. Using its SQL-like commands and leveraging its high-speed processing, it's possible to conduct comprehensive queries and data analysis on an enormous scale. This makes BigQuery an ideal tool for businesses dealing with extensive data. More information on how to analyze big data with BigQuery can be found in several documents:
-
-- [GoogleSQL](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql)
-- [Query Syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax)
-- [Creating and Using Tables](https://cloud.google.com/bigquery/docs/tables)
-- [Introduction to Views](https://cloud.google.com/bigquery/docs/views-intro)
-- [Write a Query with Duet AI](https://cloud.google.com/bigquery/docs/write-sql-duet-ai?hl=en)
-- [Loading Data](https://cloud.google.com/bigquery/docs/loading-data)
-- [Connect GA4 to BigQuery](https://support.google.com/analytics/answer/9358801?hl=en)
-
-### **Complex Data Type Handling**
-
-BigQuery can handle a wide array of data types, from simple integers and strings to more complex types like arrays and structs. This versatility allows users to analyze diverse and complex datasets, providing more depth and flexibility in data analysis.
-
-A detailed guide on how to handle complex data types in BigQuery can be found in the [Google BigQuery Data Type Documentation](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types).
-
-### Permissions & Sharing
-
-BigQuery integrates with Identity and Access Management (IAM) to provide granular control over who has access to your data. With IAM, you can assign specific roles to users and control their permissions on a project-wide or dataset-wide level. This makes it easy to manage access to your data and ensure that only authorized users can view or modify it.
-
-More information on how to manage IAM permissions in BigQuery can be found in the [IAM Permissions Documentation](https://cloud.google.com/bigquery/docs/access-control), [Control Access to Resources with IAM](https://cloud.google.com/bigquery/docs/control-access-to-resources-iam), and [Provisioning Service Accounts](https://cloud.google.com/iam/docs/service-account-overview).
-
-
- The `SM Managed WH - Admin` user role (the default role all Managed Data Warehouse customers receive) has the following permissions:
- ```
- bigquery.config.get
- bigquery.dataPolicies.create
- bigquery.dataPolicies.delete
- bigquery.dataPolicies.get
- bigquery.dataPolicies.getIamPolicy
- bigquery.dataPolicies.list
- bigquery.dataPolicies.setIamPolicy
- bigquery.dataPolicies.update
- bigquery.datasets.create
- bigquery.datasets.createTagBinding
- bigquery.datasets.delete
- bigquery.datasets.deleteTagBinding
- bigquery.datasets.get
- bigquery.datasets.getIamPolicy
- bigquery.datasets.link
- bigquery.datasets.listEffectiveTags
- bigquery.datasets.listSharedDatasetUsage
- bigquery.datasets.listTagBindings
- bigquery.datasets.setIamPolicy
- bigquery.datasets.update
- bigquery.datasets.updateTag
- bigquery.jobs.create
- bigquery.jobs.list
- bigquery.models.create
- bigquery.models.delete
- bigquery.models.export
- bigquery.models.getData
- bigquery.models.getMetadata
- bigquery.models.list
- bigquery.models.updateData
- bigquery.models.updateMetadata
- bigquery.models.updateTag
- bigquery.readsessions.create
- bigquery.readsessions.getData
- bigquery.readsessions.update
- bigquery.routines.create
- bigquery.routines.delete
- bigquery.routines.get
- bigquery.routines.list
- bigquery.routines.update
- bigquery.routines.updateTag
- bigquery.rowAccessPolicies.create
- bigquery.rowAccessPolicies.delete
- bigquery.rowAccessPolicies.getIamPolicy
- bigquery.rowAccessPolicies.list
- bigquery.rowAccessPolicies.setIamPolicy
- bigquery.rowAccessPolicies.update
- bigquery.tables.create
- bigquery.tables.createIndex
- bigquery.tables.createSnapshot
- bigquery.tables.delete
- bigquery.tables.deleteIndex
- bigquery.tables.deleteSnapshot
- bigquery.tables.export
- bigquery.tables.get
- bigquery.tables.getData
- bigquery.tables.getIamPolicy
- bigquery.tables.list
- bigquery.tables.replicateData
- bigquery.tables.restoreSnapshot
- bigquery.tables.setCategory
- bigquery.tables.setIamPolicy
- bigquery.tables.update
- bigquery.tables.updateData
- bigquery.tables.updateTag
- bigquery.transfers.get
- bigquery.transfers.update
- iam.serviceAccountKeys.create
- iam.serviceAccountKeys.delete
- iam.serviceAccountKeys.disable
- iam.serviceAccountKeys.enable
- iam.serviceAccountKeys.get
- iam.serviceAccountKeys.list
- iam.serviceAccounts.create
- iam.serviceAccounts.delete
- iam.serviceAccounts.disable
- iam.serviceAccounts.enable
- iam.serviceAccounts.get
- iam.serviceAccounts.getIamPolicy
- iam.serviceAccounts.list
- iam.serviceAccounts.setIamPolicy
- iam.serviceAccounts.undelete
- iam.serviceAccounts.update
- resourcemanager.folders.get
- resourcemanager.folders.getIamPolicy
- resourcemanager.folders.setIamPolicy
- resourcemanager.projects.get
- resourcemanager.projects.getIamPolicy
- resourcemanager.projects.list
- resourcemanager.projects.setIamPolicy
- ```
-
-
-### Computing Power & Workload Management
-
-Google BigQuery offers a unique reservation model which involves the purchase and management of what's known as "BigQuery slots". Each of these slots represents computational capacity that is utilized for running queries, thus providing an efficient way to manage large-scale data analysis tasks.
-
-Google has designed this system to be highly flexible; reservations can be allocated according to the specific needs of different projects within your organization. This provides businesses with greater control over resources, enabling more efficient management and utilization of BigQuery's powerful data analysis capabilities.
-
-Source Medium offers Managed Data Warehouse customers up to 100 slot-hours to use at their discretion (generally most businesses will never reach that quota). You can find more detailed information in the [Workload Management Documentation](https://cloud.google.com/bigquery/docs/reservations-intro).
\ No newline at end of file
diff --git a/onboarding/analytics-tools/learn-looker-studio.mdx b/onboarding/analytics-tools/learn-looker-studio.mdx
deleted file mode 100644
index a716be9..0000000
--- a/onboarding/analytics-tools/learn-looker-studio.mdx
+++ /dev/null
@@ -1,322 +0,0 @@
----
-title: "Learn Looker Studio"
-description: ""
----
-
-### Overview
-
-We know teams are busy, so in this doc we've aggregated what we feel is the most important information you need to get from 0 → 60 with SourceMedium in Looker Studio.
-
-However, if you have the time, we do recommend checking out Looker Studio's quick-start guide [here](https://support.google.com/looker-studio/answer/9171315?hl=en#zippy=) – or, if you're more of a visual learner, [this 20 minute crash course](https://www.youtube.com/watch?v=Coe_f79Xc2o&t=706s)
-
-
-
-
- A Looker Studio asset that contains a collection of **components** whose purpose is to present to viewers information and insights derived from your data.
-
- [Additional Documentation](https://support.google.com/looker-studio/answer/6309867?sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
-
-
- **Connectors** connect Looker Studio to your underlying data. Connecting to your data creates a *data source* in Looker Studio.
-
- **Data sources** represent a particular instance of a connector: for example, a connection to a specific BigQuery table or query, a Google Analytics property, or a Google Sheet. Data sources let you configure the fields and options provided by the connector used to create that connection instance. In addition, the data source gives you a secure way to share information and insights with report viewers who may not be able to directly access the underlying data.
-
- [Additional Documentation](https://support.google.com/looker-studio/answer/6268208?ref_topic=6370331&sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
-
-
- A widget that you add to a report to display your data, such as **charts**, **tables**, and interactive **date range controls** and **filter controls**. Data components get their information from a **data source**.
-
- You can also annotate your report with **text**, **shape**, **image**, and [embedded content](https://support.google.com/looker-studio/answer/9132022) components.
-
- [Additional Documentation](https://support.google.com/looker-studio/answer/6291062?ref_topic=12141289&sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
-
-
- A column of data. Looker Studio uses two basic types of fields:
- - **Dimensions** are things that you want to measure, or that serve as ways to categorize your data.
- - **Metrics** are numbers that measure the things that are contained in dimensions.
-
- [Additional Documentation](https://support.google.com/looker-studio/answer/7625527?sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
-
-
- **Edit mode** allows you to edit the structure of a report and change, add, or remove data sources, and to use interactive controls.
- - People who can edit a report or data source are referred to as **editors**.
-
- **View mode** lets you see all the data that you are authorized to see, and to use interactive controls. View mode does not allow you to modify the report structure.
- - People who can only view a report or data source are referred to as **viewers**.
-
-
- The mechanism by which a data source determines who can see the data it provides.
-
- [Additional Documentation](https://support.google.com/looker-studio/answer/6371135)
-
-
-
-
-## SourceMedium's Looker Studio templates
-
-If you're on our [Managed Data Warehouse](/data-activation/managed-data-warehouse/overview) solution, SourceMedium provides a suite of template reports and data sources for your business to leverage out-of-the-box. Learn how to use our Looker Studio templates [here](/data-activation/template-resources/looker-studio-template-copy-instructions), or checkout our template directories:
-- [Looker Studio data source templates](/data-activation/template-resources/sm-looker-data-source-template-directory)
-- [Looker Studio report templates](/data-activation/template-resources/sm-looker-report-template-directory)
-
-## Creating & Editing Data Sources
-
-Data sources are your report's connection to data that is stored somewhere -- for example your SourceMedium warehouse, a Google Sheet, Google Analytics etc.
-
-
-
- You can provision data sources directly based on tables in your BigQuery warehouse -- e.g. create a new data source out of an entire table like `obt_orders`. You can also write your own queries to derive new tables based on tables within your warehouse.
-
- The majority of your data source creation needs will be enabled via data coming from your BigQuery warehouse — using the Looker Studio BigQuery connection -- so that's what we'll focus on in this tutorial.
-
- You can create new data sources directly from your report, or from your Looker Studio home page. The steps for configuring your new data source will be the same, regardless of where you initiate the creation process.
-
-
- 
-
-
- 
-
-
-
- **Prerequisite**: you must be logged into a Google account that has access to the underlying data you wish to work with within BigQuery
-
-
- 
-
-
-
- 1. Under My Projects, select your SM managed warehouse (or other warehouse, no limits).
- 2. Then select a corresponding Dataset and Table.
- 3. Finally, press Add to create the data source
- 4. For additional information on the Datasets & Tables available from SM and their utilities, visit here.
-
- 
-
-
-
- 1. Select Custom Query from the left menu, then select your SM-managed warehouse under Projects
- 2. You can now write your query to pull data into the Custom Query box
- 3. When done, press Add to create the data source
-
- 
-
-
-
-
- See `Data source hygiene & best practices` section for more details!
-
-
-
- **Important Note**: Data sources access underlying data from your warehouse using Data Credentials — essentially, users of the data source will have access to all data the Data Credentials account has access to
- - By default, the account used to create the data source will automatically be assigned as the Data Credentials for that source
- - You can change the Data Credentials for a data source at any time
- - We recommend creating a [service account](https://cloud.google.com/iam/docs/service-account-overview) to use as the Data Credential for all of your brand's managed data sources
- - [Documentation on setting up a service account for Looker Studio](https://support.google.com/looker-studio/answer/10835295?sjid=1005066725261683010-NC#zippy=%2Cin-this-article)
- - [Additional documentation on data credentials](https://support.google.com/looker-studio/answer/6371135?hl=en#zippy=%2Cin-this-article%2Cservice-account-credentials)
-
-
- - Data Source Naming
- - We highly recommend having the Data Source name explain the underlying table / data it's referenceing
- - e.g. if you were to provision your own copy of our [DEMO] Orders OBT table, we'd recommend naming it `Orders OBT`, `Orders`, `[MyBrand] Orders OBT` etc
- - Field Naming & Field Descriptions
- - When creating a new data source from BigQuery, you'll notice computer-friendly field names containing words separated by underscores. These are the field names as they exist in your warehouse (you can look up field definitions using this field name in our Metric & Dimension documentation)
- - We encourage you to rename fields in whatever format is easiest for your team to understand!
- - If you do decide to rename fields, we very strongly encourage you to copy the original field name into the Description field, as is this is the only reference you'll have to the original field name (in case of needing to look up definitions etc.)
- - For calculated fields, we recommend including the definition in the Description field
- - Data Source Viewers don't have access to examine underlying logic for calculated fields, so it's good for all-team visibility to have that logic defined in the field Description.
- - If you've made personal duplicates of one of SourceMedium's template data sources, you'll notice that we've already renamed fields and mapped their warehouse name in the Description field
- - Please do not edit the Description field on these data sources
- - Data Source Access & Permissions
- - See `Sharing access with your team` section at the bottom of this article
-
-
-
-## Creating & Editing Reports
-
-Reports allow you to visualize your data, making it digestible for teams and stakeholders.
-
-
-
- 1. Log in to [https://lookerstudio.google.com/](https://lookerstudio.google.com/)
- - Here you'll be able to see all of the reports & data sources that you have access to.
- 2. Near the top-right of the page, find and click the `+ Create` button, and then select `Report`
- 
- 
-
- 3. You'll immediately be moved to a blank report, and asked to select data to add to the report
-
- 
- - If have already existing data sources you'd like to connect, navigate to the My data sources tab and select a source to include
- 
- - You can only select 1 data source in this step, but you can always add more later
- - If you'd like to create a new data source from data in your data warehouse, select the BigQuery connector and set up your new data source
- - If connecting a Looker-native data source (Google Ads, GA4, Search Console etc), simply select the connector, follow the authorization instructions, and select the account / view to connect
-
- 4. Once you select an initial data source to add, you'll be able to rename (recommended to do this right away) and begin editing the report!
-
-
-
-
- It's important that every page has at least 1 date range control. This control allows users to select desired ranges, which will filter charts based on the chart-level **date range dimension**.
-
- - [About date range controls](https://support.google.com/looker-studio/answer/6291067#zippy=%2Cin-this-article) & how to add them to your report
-
-
-
- Once you have your report initialized with an initial data source connected, you might want to connect additional data sources.
-
- 1. From the top navigation bar, select Resource → Manage added data sources
- 
- - Here, you'll be able to view all data sources that have been added to your report
- 2. Select `Add a Data Source`
- 
- - You'll be greeted with the same window you encountered when creating the report, asking you to select the type of data source you'd like to connect
- 3. Work through the connector-specific steps
- - [Creating copies of Source Medium template data sources](/data-activation/template-resources/looker-studio-template-copy-instructions)
-
-
-
-
-
- Once data has been added to your report, you can begin to visualize this data
-
- 1. Within the top nav-bar, select `Add a chart`, and select the chart-type you'd like to use
- 
- 
-
- - See [here](https://support.google.com/looker-studio/answer/13590887?hl=en) for additional information from Google on the available Looker Studio chart types
- 2. Drag and drop the chart to the desired location on-page
- 
-
- 3. You can now swap in the metric(s) and dimension(s) you wish to visualize!
-
-
- 
- 
-
-
- 
-
- - Make sure to pay attention to the date range dimension, which is set on each chart
- - [You can find additional info on working with charts and tables here](https://support.google.com/looker-studio/answer/6293184?hl=en#zippy=%2Cin-this-article)
-
-
-
- - [Configuring Looker Studio components](https://support.google.com/looker-studio/answer/12253817?sjid=17257856173080190020-NC#zippy=%2Cin-this-article)
- - Using the [Properties panel](https://support.google.com/looker-studio/answer/6302996?sjid=17257856173080190020-NC)
- - [Looker Studio chart types](https://support.google.com/looker-studio/answer/13590887?hl=en) & styling tips
-
-
-
-
-
-
- Outside of **date-range filtering**, there are two primary tools for filtering data in reports: **controls**, and **object-level filters**. All 3 of these concepts can be combined in various ways to create perfectly manicured and highly functional reports.
-
-
-
- There are many different types of control components, which you can explore [here](https://support.google.com/looker-studio/answer/6312144?hl=en#types-of-controls) ranging from dropdown lists to user-input boxes. By default, controls will attempt to filter all components on the page they exist on — however, you can group charts & filters together to create more manicured filtering scenarios.
-
- Controls are used when you want report users to have the ability to filter views themselves.
-
- - [Additional information on control components](https://support.google.com/looker-studio/answer/6312144?hl=en#how-controls-work&zippy=%2Cin-this-article) and how to add them to your report
-
-
-
- Object-level filters are useful when you want all users to have the same filter selection, without the ability to remove/change the filter selection. Report viewers will not have the ability to see, edit, or remove these filters.
-
- Creating an object-level filter will create a reusable filter that can be used on multiple levels (charts, pages, & reports).
-
- - [Create, edit, and manage filters](https://support.google.com/looker-studio/answer/7326859?hl=en#:~:text=Add%20a%20filter%20to%20the,%2C%20click%20%2BAdd%20a%20filter.)
- - [Additional information on filter properties (filters)](https://support.google.com/looker-studio/answer/6291066?hl=en)
-
-
-
-
-
- Calculated fields allow you to use custom logic to create new metrics & dimensions based on your data. This is provides additional flexibility, allowing you to create higher-level metrics & dimensions within charts or data sources without needing to drop into your warehouse or write any SQL.
-
- - [Learn all about creating and managing calculated fields](https://support.google.com/looker-studio/answer/6299685?hl=en#zippy=%2Cin-this-article)
-
-
- - [Adding pages and creating report structure](https://support.google.com/looker-studio/answer/6370267?hl=en#zippy=%2Cin-this-article)
-
-
-
-
-
-
-## Calculated fields — custom metrics & dimensions
-
-Calculated fields allow you to use custom logic to create new metrics & dimensions based on your data without needing to drop into your data warehouse.
-
-You can either create calculated fields directly within a report component (chart, table, filter) — for temporary or more isolated use — or you can create calculated fields at the data source level for all users to use.
-
-
- 1. Select the chart or control component you'd like to add your new field to
- 2. Select Add Metric or Add Dimension, depending on the new field you'd like to create
- 
- 
-
- - You can also select an already existing field and choose Add Field to replace an already existing metric/dimension
- 3. An in-page window will open where you can name your new field and enter your custom logic
- 
-
- 4. Once you're satisfied with your new formula, press Apply
- 
-
- 5. And you're done! You can now see your new field within the chart configuration panel, and rendered on your chart
- 
-
-
- 1. Open the data source you wish to create a calculated field on. Near the top-left of the view, select Add a field, and then select Add calculated field
- 
- 
-
- 2. A new view will open where you can name your new field and enter your custom logic
- 
-
- 3. Once you're satisfied with your new formula, press Save
- 
-
- 4. And you're done! You can now see your new field within the data source, and it can be used within any report that your data source has been added to. Be sure to update the Description for the new field, so that data source Viewers have visibility.
- 
-
-
-- [Additional documentation on Looker Studio calculated fields](https://support.google.com/looker-studio/answer/6299685?hl=en#zippy=%2Cin-this-article)
-
-## Sharing access with your team
-
-
- Looker Studio Reports have 3 levels of available access
- - **Viewer** — can simply view the report
- - **Editor** — can view, and edit the report, and add access for other team mates
- - **Owner** — can view, edit, and delete the report, and add access for other team mates
-
- [Learn how to share a report](https://support.google.com/looker-studio/answer/6287179?hl=en#zippy=%2Cin-this-article)
-
-
- In the same way that you might want to have Viewers and Editors separately for reports, we recommend setting up a similar access structure for data sources.
-
- - **Viewer** — this user can look at the data source and all of the field descriptions
- - **Editor** — this user can additionally rename fields & descriptions, edit the data source connection, and can create / edit / delete calculated fields. This user can also add view and edit access for other users
- - **Owner** — this user can additionally delete the data source, and provision access to any user type (including changing ownership of the data source to a different user)
-
- [Learn how to share a data source](https://support.google.com/looker-studio/answer/10403278?hl=en)
-
- **Note**: providing data source access to users is different than setting the [data credentials](https://support.google.com/looker-studio/answer/6371135?hl=en#zippy=%2Cin-this-article%2Cservice-account-credentials) for a data source
-
-
- To make managing access for larger teams easier, we recommend setting up Google Groups for your different user types. You can add members to these groups separately based on the access they should have to certain resources.
-
-
- - **Admin** — this group has access to all resources
- - **Data source edit** — this group has access to edit data sources. These users should have access to your Managed Warehouse.
- - **Data source view** — this group has access to view data source details. We recommend adding at least all report editors to this group
- - **Report edit** — has access to edit reports. We recommend not having too many “cooks in the kitchen” here
- - **Report view** — has access to view & use reports.
-
-
- You can find documentation on creating google groups [here](/help-center/faq/account-management-faqs/how-do-i-set-up-a-google-group).
-
-
\ No newline at end of file
diff --git a/onboarding/analytics-tools/looker-studio-guide.mdx b/onboarding/analytics-tools/looker-studio-guide.mdx
new file mode 100644
index 0000000..fdfb164
--- /dev/null
+++ b/onboarding/analytics-tools/looker-studio-guide.mdx
@@ -0,0 +1,439 @@
+---
+title: "Looker Studio Guide"
+sidebarTitle: "Looker Studio Guide"
+description: "Navigate your SourceMedium dashboard, create custom views, and understand credential modes"
+icon: "chart-line"
+---
+
+## Quick Start
+
+Your SourceMedium dashboard is built in Looker Studio (formerly Google Data Studio). Here's what you need to know to get started.
+
+### Navigating the Dashboard
+
+
+
+ Click the page dropdown (top left) or use the navigation menu to switch between report sections.
+
+
+ Use the date range picker to adjust the reporting period. Most dashboards default to the last 30 days.
+
+
+ Filter by channel, product, region, or other dimensions using the dropdown controls.
+
+
+ Hover over charts to see detailed tooltips with exact values.
+
+
+
+
+**Visual learner?** Check out [this 20 minute Looker Studio crash course](https://www.youtube.com/watch?v=Coe_f79Xc2o&t=706s) or Google's [quick-start guide](https://support.google.com/looker-studio/answer/9171315?hl=en#zippy=).
+
+
+---
+
+## Glossary
+
+Understanding these key terms will help you navigate Looker Studio effectively.
+
+
+
+ A Looker Studio asset that contains a collection of **components** (charts, tables, controls) to present insights from your data.
+
+ [Additional Documentation](https://support.google.com/looker-studio/answer/6309867?sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
+
+
+ **Connectors** connect Looker Studio to your underlying data. Connecting creates a **data source** in Looker Studio.
+
+ **Data sources** represent a particular instance of a connector—for example, a connection to a specific BigQuery table, a Google Analytics property, or a Google Sheet. Data sources let you configure fields and options, and provide a secure way to share insights with viewers who may not have direct access to the underlying data.
+
+ [Additional Documentation](https://support.google.com/looker-studio/answer/6268208?ref_topic=6370331&sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
+
+
+ A widget you add to a report to display data: **charts**, **tables**, **date range controls**, **filter controls**, etc. Data components get their information from a **data source**.
+
+ You can also add **text**, **shapes**, **images**, and [embedded content](https://support.google.com/looker-studio/answer/9132022).
+
+ [Additional Documentation](https://support.google.com/looker-studio/answer/6291062?ref_topic=12141289&sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
+
+
+ A column of data. Looker Studio uses two basic types:
+ - **Dimensions** — Categories or attributes you want to group by (e.g., `sm_channel`, `product_title`)
+ - **Metrics** — Numbers that measure things (e.g., `order_net_revenue`, `orders`)
+
+ [Additional Documentation](https://support.google.com/looker-studio/answer/7625527?sjid=14391589404630611402-NC#zippy=%2Cin-this-article)
+
+
+ The mechanism determining who can see data in a data source. See [Credential Modes](#credential-modes-explained) below.
+
+ [Additional Documentation](https://support.google.com/looker-studio/answer/6371135)
+
+
+
+---
+
+## View vs Edit Mode
+
+### View Mode (Default)
+- Interact with filters and controls
+- Hover over charts for details
+- Cannot modify dashboard structure
+
+### Edit Mode
+- Modify charts, add new visualizations
+- Change data sources and calculations
+- **Requires Editor permission**
+
+
+**Be careful in Edit mode.** Changes affect everyone who views the dashboard. If you want to experiment, make a copy first: **File → Make a copy**.
+
+
+---
+
+## Credential Modes Explained
+
+Looker Studio dashboards can use two different credential modes for data access. Understanding this helps troubleshoot "no data" issues.
+
+### Owner's Credentials (Recommended)
+
+- **How it works**: Dashboard uses the owner's BigQuery permissions
+- **Viewers see**: Data without needing their own BigQuery access
+- **Best for**: Sharing dashboards broadly within your organization
+
+### Viewer's Credentials
+
+- **How it works**: Each viewer must have their own BigQuery access
+- **Viewers see**: Only data they have permission to access
+- **Best for**: Dashboards with sensitive data requiring row-level security
+
+
+SourceMedium dashboards typically use **Owner's Credentials** so your team can view data without individual BigQuery access.
+
+
+---
+
+## SourceMedium Templates
+
+If you're on our [Managed Data Warehouse](/data-activation/managed-data-warehouse/overview) solution, SourceMedium provides template reports and data sources:
+
+- [Looker Studio Template Copy Instructions](/data-activation/template-resources/looker-studio-template-copy-instructions)
+- [Data Source Template Directory](/data-activation/template-resources/sm-looker-data-source-template-directory)
+- [Report Template Directory](/data-activation/template-resources/sm-looker-report-template-directory)
+
+---
+
+## Creating & Managing Data Sources
+
+Data sources connect your reports to data stored in BigQuery, Google Sheets, Google Analytics, etc.
+
+### Creating a New Data Source
+
+**Prerequisite**: You must be logged into a Google account with BigQuery access.
+
+
+
+ 
+
+
+ 
+
+
+
+
+
+ 
+
+
+ **From an existing table:**
+ 1. Under My Projects, select your SourceMedium warehouse
+ 2. Select a Dataset (e.g., `sm_transformed_v2`) and Table (e.g., `obt_orders`)
+ 3. Click **Add**
+
+ 
+
+ **From a custom query:**
+ 1. Select **Custom Query** from the left menu
+ 2. Select your project
+ 3. Write your SQL query
+ 4. Click **Add**
+
+ 
+
+
+ Rename your data source descriptively (e.g., "Orders OBT", "[MyBrand] Orders") and configure access.
+
+
+
+### Data Source Best Practices
+
+
+
+ Name data sources to clearly indicate the underlying table:
+ - ✅ `Orders OBT`, `[MyBrand] Orders`, `Ad Performance Daily`
+ - ❌ `Data Source 1`, `Copy of Copy of Orders`
+
+
+ BigQuery fields use `snake_case` (e.g., `order_net_revenue`). You can rename fields for readability, but:
+
+ - **Copy the original field name into the Description field** — this is your only reference for looking up definitions
+ - For calculated fields, include the formula in the Description
+ - Don't edit Descriptions on SourceMedium template data sources
+
+
+ For production data sources, use a [service account](https://cloud.google.com/iam/docs/service-account-overview) as the Data Credential:
+
+ - Ensures access survives when employees leave
+ - Centralizes permission management
+ - See [service account setup for Looker Studio](https://support.google.com/looker-studio/answer/10835295?sjid=1005066725261683010-NC#zippy=%2Cin-this-article)
+
+
+
+---
+
+## Creating & Editing Reports
+
+### Creating a Report from Scratch
+
+
+
+ Go to [lookerstudio.google.com](https://lookerstudio.google.com/), click **+ Create** → **Report**
+
+ 
+
+
+ Select an existing data source from **My data sources**, or create a new one via BigQuery.
+
+ 
+
+
+ Click the title in the top left to rename immediately—this prevents "Untitled Report" proliferation.
+
+
+
+### Adding Charts
+
+1. Click **Add a chart** in the toolbar and select a chart type
+ 
+2. Drag the chart to your desired location
+3. Configure dimensions and metrics in the **Setup** panel
+ 
+
+
+**Always set the Date Range Dimension** on time-based charts. This connects the chart to your date range control.
+
+
+For more chart types and styling options, see [Looker Studio chart types](https://support.google.com/looker-studio/answer/13590887?hl=en).
+
+### Adding Data Sources to an Existing Report
+
+1. Go to **Resource** → **Manage added data sources**
+ 
+2. Click **Add a Data Source**
+ 
+3. Select your connector and configure
+
+---
+
+## Filtering Data
+
+### Filter Controls (Interactive)
+Filter controls let **report viewers** filter data themselves using dropdowns, input boxes, etc.
+
+- By default, controls filter all components on the page
+- You can group charts with filters for more targeted filtering
+- [Control types documentation](https://support.google.com/looker-studio/answer/6312144?hl=en#types-of-controls)
+
+### Object-Level Filters (Fixed)
+Object-level filters are **pre-set by editors** and cannot be changed by viewers. They apply at the chart, page, or report level.
+
+- Use when all users should see the same filtered view
+- Viewers cannot see, edit, or remove these filters
+- [Create and manage filters](https://support.google.com/looker-studio/answer/7326859?hl=en)
+
+---
+
+## Calculated Fields
+
+Create custom metrics and dimensions without writing SQL in your warehouse.
+
+### Chart-Level Calculated Fields
+
+Quick fields created within a single chart—not reusable elsewhere.
+
+
+
+ Click on the chart where you want the custom field.
+
+
+ In the Setup panel, click **Add Metric** or **Add Dimension**, then choose **Add Field**.
+
+ 
+
+
+ Name the field and enter your formula.
+
+ 
+
+
+ Click **Apply** to add the field to your chart.
+
+ 
+
+
+
+### Data Source-Level Calculated Fields
+
+Reusable fields available in any report using that data source. **Requires data source Edit access.**
+
+
+
+ From your report: **Resource** → **Manage added data sources** → **Edit**
+
+
+ Click **Add a field** → **Add calculated field**
+
+ 
+
+
+ Name the field, enter your formula, and click **Save**.
+
+ 
+
+
+ Add the formula to the Description field so viewers understand what it calculates.
+
+ 
+
+
+
+### Common Formulas
+
+**Average Order Value (AOV)**
+```
+SUM(order_net_revenue) / COUNT_DISTINCT(sm_order_key)
+```
+
+**New Customer Revenue %**
+```
+SUM(CASE WHEN order_sequence = '1st_order' THEN order_net_revenue ELSE 0 END) / SUM(order_net_revenue)
+```
+
+**Year-over-Year Growth**
+```
+(SUM(order_net_revenue) - SUM(order_net_revenue_ly)) / SUM(order_net_revenue_ly)
+```
+
+[Full list of Looker Studio functions](https://support.google.com/looker-studio/table/6379764)
+
+---
+
+## Sharing Your Dashboard
+
+### Permission Levels
+
+| Level | View | Interact | Edit | Share | Delete |
+|-------|------|----------|------|-------|--------|
+| Viewer | ✅ | ✅ | ❌ | ❌ | ❌ |
+| Editor | ✅ | ✅ | ✅ | ✅ | ❌ |
+| Owner | ✅ | ✅ | ✅ | ✅ | ✅ |
+
+### Sharing a Report
+
+1. Click **Share** (top right)
+2. Enter email addresses or Google Group emails
+3. Choose permission level
+
+
+
+### Sharing a Data Source
+
+Data source access is **separate** from report access:
+
+- **Viewer**: Can see field names and descriptions
+- **Editor**: Can rename fields, edit calculated fields, change the connection
+- **Owner**: Can delete the data source, change ownership
+
+[Learn how to share a data source](https://support.google.com/looker-studio/answer/10403278?hl=en)
+
+
+Data source access ≠ data credentials. Access controls who can modify the data source configuration; credentials control who can see the underlying data.
+
+
+### Using Google Groups
+
+For teams with 5+ users, manage access via [Google Groups](/onboarding/analytics-tools/google-groups-access-control):
+
+| Group | Purpose |
+|-------|---------|
+| `company-sm-admins` | Full access to reports and data sources |
+| `company-sm-editors` | Report editors, data source viewers |
+| `company-sm-viewers` | Report viewers only |
+
+---
+
+## Troubleshooting
+
+
+
+ **Check these in order:**
+ 1. Date range filter — is it set to a period with data?
+ 2. Other filters — are they excluding all data?
+ 3. Data source credentials — do they have BigQuery access?
+ 4. Contact SourceMedium support if issues persist
+
+
+ Large date ranges or complex calculations slow performance. Try:
+ - Reducing the date range
+ - Using pre-aggregated metrics when available
+ - Removing unnecessary charts from the page
+
+
+ You need **Editor** permission. Contact the dashboard owner or admin.
+
+
+ - Ensure you have Editor permission
+ - Check your internet connection
+ - Try refreshing and re-entering Edit mode
+
+
+ In Edit mode:
+ 1. Click the filter control
+ 2. Check **Properties** → **Filter applied to**
+ 3. Ensure relevant charts are selected
+
+
+ - Verify you have data source Viewer or Editor access
+ - Check the data credentials match your BigQuery permissions
+ - Permission changes can take time to propagate—sign out and back in
+
+
+
+---
+
+## Keyboard Shortcuts
+
+| Action | Shortcut |
+|--------|----------|
+| Undo | `Ctrl/Cmd + Z` |
+| Redo | `Ctrl/Cmd + Y` |
+| Copy | `Ctrl/Cmd + C` |
+| Paste | `Ctrl/Cmd + V` |
+| Select All | `Ctrl/Cmd + A` |
+| Group | `Ctrl/Cmd + G` |
+
+---
+
+## Additional Resources
+
+**Google Documentation:**
+- [Looker Studio Help Center](https://support.google.com/looker-studio/)
+- [Calculated Field Functions](https://support.google.com/looker-studio/table/6379764)
+- [Chart Types Reference](https://support.google.com/looker-studio/answer/13590887?hl=en)
+- [Using the Properties Panel](https://support.google.com/looker-studio/answer/6302996?sjid=17257856173080190020-NC)
+
+**SourceMedium Resources:**
+- [Google Groups Access Control](/onboarding/analytics-tools/google-groups-access-control)
+- [BigQuery Essentials](/onboarding/analytics-tools/bigquery-essentials)
+- [Connect BigQuery to Looker Studio](/onboarding/analytics-tools/connect-bigquery-to-looker-studio)
+- [Use SourceMedium Data in Other BI Tools](/onboarding/analytics-tools/connect-to-other-bi-tools)
+- [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2/index)
diff --git a/onboarding/analytics-tools/sharing-access.mdx b/onboarding/analytics-tools/sharing-access.mdx
deleted file mode 100644
index d81023d..0000000
--- a/onboarding/analytics-tools/sharing-access.mdx
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: 'Granting Access to View & Edit Access Your Dashboard or Configuration Sheet'
-sidebarTitle: 'Sharing Access to SourceMedium'
-description: ""
----
-
-Google's ecosystem makes it easy to to share and manage the level of access granted to indivualas or Google groups.
-
-[We recommend setting up Google Groups first](/onboarding/analytics-tools/creating-google-groups) for your different user types based on the access they should have to the dashboard and configuration sheet.
-
-## Giving Access to A Dashboard or Google Sheet
-
-### Step 1: Access the Share Menu
-
-- Navigate to the Share Button on the top right side of your Dashboard or Google Sheet.
- 
-
- 
-
-- In the Share menu that appears, click the text box.
-
- 
-
-### Step 2: Grant Your Group's Level of Access
-
-- Enter your access group's or an individual email address followed by a comma (or hit the enter key). This will allow for multiple groups or individuals to be given the same level of access at once.
-
- 
-
-- Choose the level of access you want to be given to the entered email addresses (Viewer is the default level).
-
- 
-
-- Choose if you want to notify the group members or individuals of their access by checking or unchecking the box in the bottom left of the Share window.
-
- 
-
-- Once you have made all selections, click Send in the bottom right of the Share window.
\ No newline at end of file
diff --git a/onboarding/data-docs/data-hygeine/importance-of-good-data-hygeine.mdx b/onboarding/data-docs/data-hygeine/importance-of-good-data-hygeine.mdx
index 4754791..fe6e46a 100644
--- a/onboarding/data-docs/data-hygeine/importance-of-good-data-hygeine.mdx
+++ b/onboarding/data-docs/data-hygeine/importance-of-good-data-hygeine.mdx
@@ -1,4 +1,25 @@
---
-title: "Importance of Good Data Hygeine"
-sidebarTitle: "Good Data Hygeine"
----
\ No newline at end of file
+title: "Importance of good data hygiene"
+sidebarTitle: "Good data hygiene"
+description: "Why clean, consistent data matters for accurate reporting and how to avoid common data-quality pitfalls"
+icon: "heart-pulse"
+---
+
+Good data hygiene makes reporting more trustworthy and reduces time spent reconciling differences across tools.
+
+## What “good hygiene” means
+
+- Consistent naming conventions for channels, campaigns, and UTMs
+- Stable identifiers (customer, order, product) across systems
+- Clear definitions for metrics (gross vs net, refunds, cancellations)
+
+## Common causes of reporting issues
+
+- Missing or inconsistent UTMs (especially for email/SMS and subscriptions)
+- Timezone mismatches across platforms
+- Changes to orders after purchase (edits, refunds, cancellations)
+
+## What to do next
+
+- Standardize UTMs: [UTM Setup](/help-center/core-concepts/attribution/utm-setup)
+- Learn why sources differ: [Why would external reports not match the SourceMedium dashboard?](/help-center/faq/data-faqs/why-would-external-reports-not-match-the-sourcemedium-dashboard)
diff --git a/onboarding/data-docs/dimensions.mdx b/onboarding/data-docs/dimensions.mdx
index f54715f..b482349 100644
--- a/onboarding/data-docs/dimensions.mdx
+++ b/onboarding/data-docs/dimensions.mdx
@@ -1,8 +1,113 @@
---
title: "Dimension Definitions"
-desecription: "Dimensions are qualitative values that add crucial context to metric values"
-icon: ""
+description: "Definitions and examples for common SourceMedium dimensions used in reporting and filtering"
+icon: "filter"
---
-| Dimension Name | Dimension Definition | Further Documentation |
-| --- | --- | --- |
+Dimensions are attributes used to slice and filter your data. This reference covers the most common dimensions across SourceMedium tables.
+
+
+For full column documentation, see [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2).
+
+
+## Channel & Attribution Dimensions
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `sm_channel` | Primary channel classification for orders and marketing | `online_dtc`, `amazon`, `retail`, `wholesale` |
+| `sm_sub_channel` | Granular breakdown within a channel (config-sheet or platform-derived; falls back to channel) | `Fulfilled by Amazon`, `Fulfilled by Merchant`, `Online DTC` |
+| `sm_utm_source` | UTM source (when available) | `facebook`, `google`, `klaviyo`, `direct` |
+| `sm_utm_medium` | UTM medium (when available) | `cpc`, `email`, `organic`, `referral` |
+| `sm_utm_campaign` | UTM campaign (when available) | `spring_sale_2026`, `retargeting_lookalike` |
+| `sm_utm_source_medium` | Convenience combined source/medium | `facebook / cpc` |
+
+## Customer Dimensions
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `customer_tags_array` | Customer tags as an array (preferred for exact matching) | `VIP`, `wholesale`, `influencer` |
+| `customer_tags_csv` | Customer tags as a comma-separated string | `VIP, wholesale` |
+
+## Order Dimensions
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `is_order_sm_valid` | Whether order should be included in reporting | `TRUE`, `FALSE` |
+| `order_payment_status` | Payment/financial status | `paid`, `refunded`, `partially_refunded` |
+| `order_discount_codes_csv` | Discount codes applied to the order | `SUMMER20, INFLUENCER10` |
+| `order_product_tags_array` | Tags across products in the order (array) | `subscription`, `gift` |
+| `sm_valid_order_index` | Sequential index of valid orders per customer | `1`, `2`, `3` |
+
+## Product Dimensions
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `product_type` | Shopify product type | `T-Shirt`, `Supplement`, `Accessory` |
+| `product_vendor` | Product vendor/brand | `Nike`, `In-house`, `Partner Brand` |
+| `product_tags_array` | Shopify product tags (array) | `bestseller`, `new-arrival`, `sale` |
+| `product_collection_titles_csv` | Product collection membership | `Summer 2026`, `Basics`, `Limited Edition` |
+
+## Time Dimensions
+
+| Dimension | Definition | Notes |
+|-----------|------------|-------|
+| `order_created_at` | Order timestamp (UTC) | Use for filtering by date range |
+| `order_created_at_local_datetime` | Order timestamp (brand timezone) | Use for time-of-day analysis |
+| `date` | Date for aggregated report tables | In `rpt_*` tables |
+
+## Geographic Dimensions
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `order_shipping_country_code` | Shipping destination country code | `US`, `CA`, `GB` |
+| `order_shipping_state` | Shipping destination state/province | `CA`, `NY`, `ON` |
+| `order_shipping_city` | Shipping destination city | `Los Angeles`, `New York` |
+
+## Marketing Dimensions (Ad Performance)
+
+| Dimension | Definition | Example Values |
+|-----------|------------|----------------|
+| `source_system` | Advertising platform source | `meta_ads`, `google_ads`, `tiktok` |
+| `ad_campaign_name` | Campaign name from ad platform | `Prospecting - Lookalike` |
+| `ad_group_name` | Ad group/ad set name | `Interest - Fitness` |
+| `ad_name` | Individual ad name | `Video - Testimonial v2` |
+
+## Common Filtering Patterns
+
+### Filter to valid orders
+```sql
+SELECT COUNT(*) AS valid_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE;
+```
+
+### Filter by channel
+```sql
+SELECT COUNT(*) AS valid_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND sm_channel = 'online_dtc';
+```
+
+### Filter by date range
+```sql
+SELECT COUNT(*) AS valid_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND order_created_at >= '2026-01-01'
+ AND order_created_at < '2026-02-01';
+```
+
+### Filter by customer type
+```sql
+SELECT COUNT(*) AS first_valid_orders
+FROM `your_project.sm_transformed_v2.obt_orders`
+WHERE is_order_sm_valid = TRUE
+ AND sm_valid_order_index = 1;
+```
+
+## Related Resources
+
+- [Glossary](/help-center/glossary) — Term definitions
+- [Metric Definitions](/onboarding/data-docs/metrics) — Calculated metrics
+- [Data Tables Reference](/data-activation/data-tables/sm_transformed_v2) — Full table documentation
diff --git a/onboarding/data-docs/metrics.mdx b/onboarding/data-docs/metrics.mdx
index cd3ab95..ad4ec75 100644
--- a/onboarding/data-docs/metrics.mdx
+++ b/onboarding/data-docs/metrics.mdx
@@ -1,23 +1,188 @@
---
title: "Metric Definitions"
-desecription: "Metrics are quantitative values that can be summed, averaged, and otherwise aggregated"
-icon: ""
+description: "Definitions for SourceMedium metrics used across dashboards and the semantic layer"
+icon: "chart-line"
---
-
-
-
-
-
- foo
-
-
- bar
-
-
-
-
- Cost per Acquisition = Spend / New Customers
-
-
-| Metric Name | Metric Definition | Further Documentation |
-| --- | --- | --- |
+
+This reference documents the key metrics available in SourceMedium dashboards and the semantic layer. Metrics are organized by category.
+
+
+**Complete Metric Reference**: For a comprehensive, always-current list of all 180+ metrics, query the [`dim_semantic_metric_catalog`](/data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog) table in your warehouse. This page provides a curated overview of the most commonly used metrics.
+
+
+
+Metrics marked as "Alias" are legacy names maintained for backward compatibility. Use the preferred metric name for new queries.
+
+
+## Revenue Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **Average Order Value (AOV) - Net** | Average net revenue per order | Ratio |
+| **Average Order Value (AOV) - Gross** | Average gross revenue per order | Ratio |
+| **Average Order Value (AOV) - Total** | Average total revenue per order (including shipping/taxes) | Ratio |
+| **Order Net Revenue** | Net revenue after discounts and refunds | Simple |
+| **Order Gross Revenue** | Gross revenue before discounts and refunds | Simple |
+| **Order Total Revenue** | Total revenue including shipping and taxes | Simple |
+| **New Customer Net Revenue** | Net revenue from first-time customers | Simple |
+| **Repeat Customer Net Revenue** | Net revenue from repeat customers | Simple |
+| **Gross Profit** | Revenue minus cost of goods sold | Simple |
+| **Gross Margin %** | Gross profit as percentage of net revenue | Ratio |
+| **Total Discounts** | Total discount amount applied to orders | Simple |
+| **Total Refunds** | Total refund amount processed | Simple |
+
+## Customer Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **New Customers** | Count of newly acquired customers in the period | Simple |
+| **Total Customers** | Total count of all customers | Simple |
+| **New Customer Order Count** | Number of first-time customer orders | Simple |
+| **Repeat Customer Order Count** | Number of repeat customer orders | Simple |
+| **Active Subscribers** | Count of customers with active subscriptions | Simple |
+| **Churned Subscribers** | Count of customers with churned subscriptions | Simple |
+| **Email Subscribers** | Count of customers opted into email marketing | Simple |
+| **SMS Subscribers** | Count of customers opted into SMS marketing | Simple |
+| **Customer Acquisition Cost (CAC)** | Average cost to acquire a new customer | Ratio |
+| **Subscriber Churn Rate** | Percentage of subscribers who have churned | Ratio |
+
+## Marketing Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **Total Ad Spend** | Total advertising spend across all platforms | Simple |
+| **Total Ad Clicks** | Total clicks across all ad platforms | Simple |
+| **Total Ad Impressions** | Total impressions across all ad platforms | Simple |
+| **Marketing Efficiency Ratio (MER)** | Total revenue divided by total ad spend (blended ROAS) | Ratio |
+| **Return on Ad Spend (ROAS)** | Revenue generated per dollar of ad spend | Ratio |
+| **Cost Per Click (CPC)** | Average cost per ad click | Ratio |
+| **Cost Per Order (CPO)** | Average advertising cost per order | Ratio |
+| **Cost Per Thousand Impressions (CPM)** | Cost per thousand impressions | Derived |
+| **Click-Through Rate (CTR)** | Percentage of impressions that result in clicks | Ratio |
+| **Platform Reported Conversions** | Conversions as reported by ad platforms | Simple |
+| **Platform Return on Ad Spend** | Return on ad spend as reported by platforms | Ratio |
+
+## Conversion Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **Site Conversion Rate** | Overall conversion rate (orders / website sessions) | Ratio |
+| **Simple Conversion Rate** | Orders / sessions using executive summary data | Ratio |
+| **Add to Cart Rate** | Percentage of page views that result in add to cart | Ratio |
+| **Checkout Initiation Rate** | Percentage of add to carts that proceed to checkout | Ratio |
+| **Checkout Completion Rate** | Percentage of checkouts that complete purchase | Ratio |
+| **Discount Rate %** | Discounts as percentage of gross revenue | Ratio |
+| **Refund Rate %** | Refunds as percentage of gross revenue | Ratio |
+| **Email Opt-in Rate** | Percentage of customers opted into email marketing | Ratio |
+| **SMS Opt-in Rate** | Percentage of customers opted into SMS marketing | Ratio |
+
+## Cumulative / Period Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **MTD Net Revenue** | Month-to-date net revenue | Cumulative |
+| **MTD Order Count** | Month-to-date order count | Cumulative |
+| **MTD New Customers** | Month-to-date new customer acquisitions | Cumulative |
+| **MTD Ad Spend** | Month-to-date advertising spend | Cumulative |
+| **QTD Net Revenue** | Quarter-to-date net revenue | Cumulative |
+| **YTD Net Revenue** | Year-to-date net revenue | Cumulative |
+| **Trailing 30 Day Revenue** | Revenue for the last 30 days | Cumulative |
+| **Trailing 90 Day Revenue** | Revenue for the last 90 days | Cumulative |
+
+## Product Metrics
+
+| Metric | Description | Type |
+|--------|-------------|------|
+| **Total Products** | Total count of unique products in catalog | Simple |
+| **Total SKUs** | Total count of product variants/SKUs | Simple |
+| **Product Page Views** | Count of product page views | Simple |
+| **Product Cost (COGS)** | Total cost of goods sold | Simple |
+| **SKUs per Product** | Average number of variants per product | Ratio |
+
+## Legacy Aliases
+
+These metric names are maintained for backward compatibility. **Always use the preferred name for new implementations.**
+
+### Core Aliases
+
+| Alias | Preferred Metric | Description |
+|-------|------------------|-------------|
+| `aov` | `average_order_value_net` | Average Order Value |
+| `mer` | `marketing_efficiency_ratio` | Marketing Efficiency Ratio |
+| `cac` | `customer_acquisition_cost` | Customer Acquisition Cost |
+| `cpc` | `cost_per_click` | Cost Per Click |
+| `cpm` | `cost_per_thousand_impressions` | Cost Per Mille |
+| `roas` | `return_on_ad_spend` | Return on Ad Spend |
+| `ctr` | `click_through_rate` | Click-Through Rate |
+| `cpo` | `cost_per_order` | Cost Per Order |
+| `cvr` | `conversion_rate` | Conversion Rate |
+| `cpa` | `customer_acquisition_cost` | Cost Per Acquisition (same as CAC) |
+
+### AOV Variants
+
+| Alias | Preferred Metric |
+|-------|------------------|
+| `aov_gross` | `average_order_value_gross` |
+| `aov_net_revenue` | `average_order_value_net` |
+| `aov_gross_revenue` | `average_order_value_gross` |
+| `aov_total_revenue` | `average_order_value_total` |
+| `aov_new_customers` | `average_order_value_new_customer_net` |
+| `aov_new_customer_net_revenue` | `average_order_value_new_customer_net` |
+| `aov_new_customer_gross_revenue` | `average_order_value_new_customer_gross` |
+| `aov_new_customer_total_revenue` | `average_order_value_new_customer_total` |
+| `aov_repeat_customer_net_revenue` | `average_order_value_repeat_customer_net` |
+| `aov_repeat_customer_gross_revenue` | `average_order_value_repeat_customer_gross` |
+| `aov_repeat_customer_total_revenue` | `average_order_value_repeat_customer_total` |
+
+### Marketing Variants
+
+| Alias | Preferred Metric |
+|-------|------------------|
+| `mer_new_customers` | `marketing_efficiency_ratio_new_customers` |
+| `cvr_new_customers` | `conversion_rate_new_customers` |
+| `platform_roas` | `platform_return_on_ad_spend` |
+| `platform_mer` | `platform_marketing_efficiency_ratio` |
+| `platform_cpc` | `platform_cost_per_conversion` |
+| `platform_rpc` | `platform_revenue_per_conversion` |
+| `platform_rpm` | `platform_revenue_per_thousand_impressions` |
+| `cpo_platform` | `cost_per_platform_conversion` |
+| `cpa_marketing` | `cost_per_platform_conversion` |
+
+
+Query `dim_semantic_metric_catalog` with `WHERE is_abbreviation = true` to see all available aliases in your warehouse.
+
+
+## Metric Types
+
+- **Simple**: Direct aggregation of a measure (e.g., SUM of revenue)
+- **Ratio**: Division of two metrics (e.g., revenue / orders = AOV)
+- **Derived**: Calculation involving other metrics with custom expressions
+- **Cumulative**: Running total over a time period (e.g., MTD revenue)
+
+## Discovering More Metrics
+
+The semantic layer includes 180+ metrics across all categories. To explore the complete list:
+
+```sql
+-- List all metrics by category
+SELECT
+ metric_category,
+ metric_name,
+ metric_label,
+ metric_type
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+ORDER BY metric_category, metric_name
+```
+
+```sql
+-- Find metrics matching a keyword
+SELECT
+ metric_name,
+ metric_description,
+ calculation
+FROM `your_project.sm_metadata.dim_semantic_metric_catalog`
+WHERE LOWER(metric_name) LIKE '%revenue%'
+ OR LOWER(metric_description) LIKE '%revenue%'
+```
+
+See the [dim_semantic_metric_catalog documentation](/data-activation/data-tables/sm_metadata/dim_semantic_metric_catalog) for more query examples and detailed schema information.
diff --git a/onboarding/data-docs/tables/customer_details_dda.mdx b/onboarding/data-docs/tables/customer_details_dda.mdx
deleted file mode 100644
index e28ba31..0000000
--- a/onboarding/data-docs/tables/customer_details_dda.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Table: Customer Details'
-description: 'Working with the `customer_details` table in BigQuery'
-icon: 'map'
----
\ No newline at end of file
diff --git a/onboarding/data-docs/tables/customer_details_looker.mdx b/onboarding/data-docs/tables/customer_details_looker.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/onboarding/data-docs/tables/executive_summary_dda.mdx b/onboarding/data-docs/tables/executive_summary_dda.mdx
deleted file mode 100644
index 92d0a2f..0000000
--- a/onboarding/data-docs/tables/executive_summary_dda.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Table: Executive Summary'
-description: 'Working with the `executive_summary` table in BigQuery'
-icon: 'map'
----
\ No newline at end of file
diff --git a/onboarding/data-docs/tables/executive_summary_looker.mdx b/onboarding/data-docs/tables/executive_summary_looker.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/onboarding/data-docs/tables/order_details_dda.mdx b/onboarding/data-docs/tables/order_details_dda.mdx
deleted file mode 100644
index 8e42395..0000000
--- a/onboarding/data-docs/tables/order_details_dda.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Table: Order Details'
-description: 'Working with the `order_details` table in BigQuery'
-icon: 'map'
----
\ No newline at end of file
diff --git a/onboarding/data-docs/tables/order_details_looker.mdx b/onboarding/data-docs/tables/order_details_looker.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b.mdx b/onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b.mdx
index 1ef72b8..6c55f12 100644
--- a/onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b.mdx
+++ b/onboarding/getting-started/cold-start/how-your-data-gets-from-point-a-to-b.mdx
@@ -1,5 +1,7 @@
---
title: "How your data gets from point A to B"
+description: "High-level overview of how SourceMedium ingests, transforms, and delivers data for reporting"
+icon: "book"
---

@@ -7,7 +9,10 @@ title: "How your data gets from point A to B"
Our **data model** integrates and cleans your platforms’ data into a master table that each module of the
dashboard interacts with differently depending on the purpose of the module.
-We use data from your sales platform (Shopify, Amazon, etc) as the “source of truth” for all sales-based reporting.
+We use **Intelligent Data Aggregation** to build this model—merging first-party signals from all your platforms to ensure your data is as usable, trustworthy, and high-quality as possible.
+
+- **Sales Reporting**: We use data from your sales platform (Shopify, Amazon, etc.) as the core "source of truth" for financial reporting.
+- **Attribution**: We aggregate signals from all connected sources to resolve the most accurate last-click and multi-touch attribution.
@@ -22,5 +27,5 @@ We use data from your sales platform (Shopify, Amazon, etc) as the “source of
If you notice any mismatch between your Shopify Sales Report and your Executive Summary,
- see [this article](/help-center/faq/data-faqs/exec-summ-vs-shopify-sales-report) for possible explanations.
-
\ No newline at end of file
+ see [this article](/help-center/faq/data-faqs/why-dont-the-executive-summary-and-shopifys-sales-report-match) for possible explanations.
+
diff --git a/onboarding/getting-started/data-volume-assessment.mdx b/onboarding/getting-started/data-volume-assessment.mdx
new file mode 100644
index 0000000..2988a69
--- /dev/null
+++ b/onboarding/getting-started/data-volume-assessment.mdx
@@ -0,0 +1,181 @@
+---
+title: "Assess Your Data Volume Before Onboarding"
+sidebarTitle: "Data Volume Assessment"
+description: "Run a quick ShopifyQL query to understand your historical data volume and set expectations for onboarding timeline"
+icon: "gauge-high"
+---
+
+Before starting your SourceMedium integration, it's helpful to understand your Shopify store's historical data volume. This helps us set accurate expectations for your onboarding timeline and plan the best ingestion strategy.
+
+
+**Why does data volume matter?**
+
+SourceMedium ingests your complete historical data to power accurate LTV calculations, cohort analysis, and customer journey insights. Larger data volumes take longer to process—and for very large stores, we may recommend a phased approach to get you up and running faster.
+
+
+## What You'll Need
+
+- **Shopify Admin access** with permissions to view Analytics/Reports
+- **5 minutes** to run a simple query and share the results
+
+## Step-by-Step Instructions
+
+
+
+
+
+1. Log into your **Shopify Admin** at `https://your-store.myshopify.com/admin`
+2. Click **Analytics** in the left sidebar
+3. Click the **Reports** tab (or go to **Analytics → Reports**)
+4. Click **Create custom report** (or look for "Explore" / "New exploration")
+
+
+The ShopifyQL Editor is available in Shopify Admin under Analytics → Reports. The exact UI may vary depending on your Shopify plan and permissions.
+
+
+
+
+
+
+Copy this entire query and paste it into the ShopifyQL Editor:
+
+```sql
+FROM sales
+SHOW
+ orders AS "Order Count",
+ quantity_ordered AS "Units Sold",
+ customers AS "Customer Count"
+TIMESERIES year WITH TOTALS
+SINCE 2010-01-01
+UNTIL today
+ORDER BY year DESC
+```
+
+
+**About the `SINCE` date:** We use 2010 to capture most stores' full history. If your store is older, adjust to an earlier date. ShopifyQL will only return data from when your store actually started.
+
+
+
+
+
+
+Click the **Run** button (or press `Cmd/Ctrl + Enter`) to execute the query.
+
+You'll see a table with one row per year showing:
+- **Order Count** — Number of orders placed that year
+- **Units Sold** — Total quantity of items sold (e.g., an order with 2 shirts and 1 hat = 3 units)
+- **Customer Count** — Number of unique customers that year
+
+**Example output:**
+
+| Year | Order Count | Units Sold | Customer Count |
+|------|-------------|------------|----------------|
+| Current year (YTD) | 85,000 | 190,000 | 60,000 |
+| ... | ... | ... | ... |
+| 2021 | 180,000 | 400,000 | 125,000 |
+| 2020 | 120,000 | 260,000 | 85,000 |
+| 2019 | 45,000 | 95,000 | 32,000 |
+
+The **Totals** row at the bottom gives you the overall numbers across all years.
+
+
+
+
+
+Take a screenshot of the table or copy the numbers and share them with your SourceMedium onboarding contact via Slack or email.
+
+A screenshot of the results works great, or just copy/paste the table. Include:
+- The year-by-year breakdown
+- Your total order count
+- When your store launched (first year with data)
+
+
+
+
+
+---
+
+## What Happens With Your Results
+
+Once you share your data volume, your SourceMedium contact will confirm your expected onboarding timeline.
+
+**We always prefer full historical ingestion** — it gives you the most accurate LTV calculations, complete cohort analysis, and reliable year-over-year comparisons.
+
+For very high-volume stores (think: 10+ years of history, millions of orders), full ingestion may take longer. If you have a specific go-live deadline, let us know and we can discuss options—such as starting with recent data while full history loads in the background.
+
+
+**Why does historical data matter?**
+
+Lifetime Value (LTV) calculations depend on seeing a customer's complete purchase history. If we only load 2 years of data, a customer who first purchased 5 years ago will appear as a "new" customer—which understates their true LTV.
+
+Once full history is loaded, all calculations automatically update to reflect complete customer journeys.
+
+
+---
+
+## Frequently Asked Questions
+
+
+
+
+
+The exact location varies by Shopify plan and UI version. Try:
+
+- Go to **Analytics → Reports** and look for "Create custom report" or "Explore"
+- Go directly to: `https://your-store.myshopify.com/admin/reports`
+
+If you still can't find it, take a screenshot of what you see under Analytics and share it with us—we'll help.
+
+
+
+
+
+Common issues:
+
+1. **"Syntax error"** — Make sure you copied the entire query exactly, including the line breaks.
+
+2. **"No data returned"** — Your store may be very new. That's fine—just let us know.
+
+3. **"Access denied"** — You may need different permissions. Ask your store owner to run it, or share what you see and we'll help.
+
+
+
+
+
+Yes — change `TIMESERIES year` to `TIMESERIES quarter` in the query. This is helpful if you want to see seasonal patterns.
+
+
+
+
+
+These counts determine how long data ingestion takes:
+
+- **Orders** — The primary driver of ingestion time
+- **Units Sold** — Shows data density; more units per order means more data per order
+- **Customers** — Used for LTV calculations, cohort analysis, and customer journey insights
+
+Order count is the best single predictor of ingestion time, but units sold gives us a sense of how much data each order contains.
+
+
+
+
+
+If you have a specific go-live deadline and your data volume is high, let your SourceMedium contact know during onboarding. We can discuss options like starting with recent data while full history loads in the background.
+
+
+
+
+
+---
+
+## What Happens Next
+
+After sharing your data volume assessment:
+
+1. **We'll confirm your onboarding timeline** — Based on your volume, we'll set realistic expectations
+2. **You'll receive integration instructions** — Follow our [Shopify Integration Guide](/data-inputs/platform-integration-instructions/shopify-integration) to grant access
+3. **Data ingestion begins** — We'll start pulling your data and notify you when it's ready for review
+
+
+ Continue to Shopify Integration Instructions →
+
diff --git a/onboarding/getting-started/getting-started-checklist.mdx b/onboarding/getting-started/getting-started-checklist.mdx
index c12766f..b7c378f 100644
--- a/onboarding/getting-started/getting-started-checklist.mdx
+++ b/onboarding/getting-started/getting-started-checklist.mdx
@@ -23,7 +23,11 @@ In this document, you'll find the steps and resources to get you started with So
__Your onboarding and implementation team will share a unique link to our data integrations app, which you can use to grant us access to your data sources__.
- Included below is a prioritized list of data sources you'll want to integrate to get you up and running as quickly as
+
+ **Large store?** If your Shopify store has been running for 5+ years or processes high order volumes, consider running our [Data Volume Assessment](/onboarding/getting-started/data-volume-assessment) first. This helps us plan the optimal ingestion strategy and set accurate timeline expectations.
+
+
+ Included below is a prioritized list of data sources you'll want to integrate to get you up and running as quickly as
possible.
While we've automated the connection process for many of these data sources __(please see note about our integrations app above)__, our
@@ -44,12 +48,6 @@ In this document, you'll find the steps and resources to get you started with So
- - [Google Analytics Universal](/data-inputs/platform-integration-instructions/ga-universal-integration)
- - [Google Analytics 4](/data-inputs/platform-integration-instructions/ga4-integration)
-
-
-
- - [Google Analytics Universal](/data-inputs/platform-integration-instructions/ga-universal-integration)
- [Google Analytics 4](/data-inputs/platform-integration-instructions/ga4-integration)
@@ -94,4 +92,4 @@ In this document, you'll find the steps and resources to get you started with So
Questions? Reach out on Slack or email support@sourcemedium.com
-
\ No newline at end of file
+
diff --git a/onboarding/getting-started/how-to-manage-user-access.mdx b/onboarding/getting-started/how-to-manage-user-access.mdx
index bb3968a..4216e36 100644
--- a/onboarding/getting-started/how-to-manage-user-access.mdx
+++ b/onboarding/getting-started/how-to-manage-user-access.mdx
@@ -9,10 +9,10 @@ iconType: "solid"
### Introduction
Whether you're a brand marketing team or an agency servicing many brands, managing user access is a critical part of
-harnessing Source Medium's data infrastructure and reporting. Industry best practices dictate that access should be given
+harnessing SourceMedium's data infrastructure and reporting. Industry best practices dictate that access should be given
*only as needed*$~$ to achieve stalwart data security and reliable stability of custom analytics, tables, views, and pipelines
-built upon Source Medium's infrastructure. Find out how to protect the security of your data and the reliability of custom tools
-you build on Source Medium using the information below.
+built upon SourceMedium's infrastructure. Find out how to protect the security of your data and the reliability of custom tools
+you build on SourceMedium using the information below.
@@ -28,7 +28,7 @@ you build on Source Medium using the information below.
This is the safest permission to grant, suitable for anyone who can be trusted to look at your data.
__How to Set this Permission:__
- Set this permission on your Source Medium Dashboard, which is always accessed from the link provided during your onboarding and
+ Set this permission on your SourceMedium Dashboard, which is always accessed from the link provided during your onboarding and
pinned to your shared slack channel, should you choose to have one, otherwise provided by email. Use the Share button at the top right
to add users by email as shown in the gif below.
@@ -46,7 +46,7 @@ you build on Source Medium using the information below.
This permission does not allow for editing of the underlying data or the creation of custom fields at the data source level.
__How to Set this Permission:__
- Set this permission on your Source Medium Dashboard, which is always accessed from the link provided during your onboarding and
+ Set this permission on your SourceMedium Dashboard, which is always accessed from the link provided during your onboarding and
pinned to your shared slack channel, should you choose to have one, otherwise provided by email. Use the Share button at the top right
to add users by email as shown in the gif below.
@@ -66,7 +66,7 @@ you build on Source Medium using the information below.
This permission is set in multiple places. First, it is set on each data source in Looker Studio at the top of the edit screen with the heading
"Data credentials." For embedded data sources, the "Owner's Credentials" option from this menu will allow anyone with edit access to the report
to edit the data source. For reusable data sources, and when the data credentials are set to "Viewer's Credentials," the user must have edit access
- to the data source on its original platform, e.g Big Query, Google Analytics, in order to edit the data source.
+ to the data source on its original platform, e.g BigQuery, Google Analytics, in order to edit the data source.
@@ -74,27 +74,27 @@ you build on Source Medium using the information below.
[Editing Data Sources from Google](https://support.google.com/looker-studio/answer/7178497?hl=en#zippy=%2Cin-this-article)
-
+ $~$ __Responsibility Rating: Moderate__
- Brief explanation of what the permission means/is capable of
- How to set the permission, including a screenshot
- Link to the relevant permission doc on google
- (Looker Studio, Big Query, and/or Google groups)
+ (Looker Studio, BigQuery, and/or Google groups)
-
+ $~$ __Responsibility Rating: Very High__
- Brief explanation of what the permission means/is capable of
- How to set the permission, including a screenshot
- Link to the relevant permission doc on google
- (Looker Studio, Big Query, and/or Google groups)
+ (Looker Studio, BigQuery, and/or Google groups)
-### $~$ Source Medium Recommended Access Group Setup
+### $~$ SourceMedium Recommended Access Group Setup
Hover over me
@@ -103,7 +103,7 @@ you build on Source Medium using the information below.
- __Permissions:__
_Looker Studio - View_
- _Big Query - None_
+ _BigQuery - None_
- __Who this is for:__ Marketing team, Analysts, Client Team Members for Marketing Agencies—anyone who needs access to the data
but doesn’t want to overcomplicate the process with editing
@@ -111,7 +111,7 @@ you build on Source Medium using the information below.
- __Permissions:__
_Looker Studio - Edit Dashboards_
- _Big Query - None_
+ _BigQuery - None_
- __Who this is for:__ Analysts, Data Team Members, and any tech savvy employees that not only need data access, but need to
create custom visualizations, use templates, and copy dashboards to answer their analytical questions on the fly
@@ -119,17 +119,17 @@ you build on Source Medium using the information below.
- __Permissions:__
_Looker Studio - Edit Dashboards & Data Sources_
- _Big Query - View Tables_
+ _BigQuery - View Tables_
- __Who this is for:__ Deep Analysts, Data Team Members, and the most tech knowledgeable employees looking to answer the most
- complex analytical questions using the full power of Looker Studio and understanding the underlying data by observing Big Query data frameworks
+ complex analytical questions using the full power of Looker Studio and understanding the underlying data by observing BigQuery data frameworks
- __Permissions:__
_Looker Studio - Edit Dashboards & Data Sources_
- _Big Query - Edit Tables_
+ _BigQuery - Edit Tables_
- __Who this is for:__ Data Engineers, Data Team Managers, and data employees
who need to create and edit tables in the warehouse
-
\ No newline at end of file
+
diff --git a/onboarding/getting-started/how-to-work-with-the-sourcemedium-team.mdx b/onboarding/getting-started/how-to-work-with-the-sourcemedium-team.mdx
index 9cf2943..8f5011d 100644
--- a/onboarding/getting-started/how-to-work-with-the-sourcemedium-team.mdx
+++ b/onboarding/getting-started/how-to-work-with-the-sourcemedium-team.mdx
@@ -1,5 +1,6 @@
---
title: " How to Work With Us"
+description: "Onboarding guide: How to Work With Us."
icon: "business-time"
iconType: "solid"
---
@@ -9,4 +10,4 @@ Our CSAs (Customer Solutions Analysts) are experts in helping your team get the
- The fastest form of communication is through your **shared slack channel**, if you've set one up. Alternatively, the team can be reached at: [support@sourcemedium.com](mailto:customersuccess@sourcemedium.com)
#### Customization Requests
-Please let us know if your team prefers **Notion** or **Google Docs**, which will be used to log company specific resources and for future customization scoping.
\ No newline at end of file
+Please let us know if your team prefers **Notion** or **Google Docs**, which will be used to log company specific resources and for future customization scoping.
diff --git a/onboarding/getting-started/intro-to-sm.mdx b/onboarding/getting-started/intro-to-sm.mdx
index 550bcbc..79c63c0 100644
--- a/onboarding/getting-started/intro-to-sm.mdx
+++ b/onboarding/getting-started/intro-to-sm.mdx
@@ -1,20 +1,22 @@
---
-title: "What is SourceMedium?"
+title: "SourceMedium Product Tour"
+description: "A high-level tour of SourceMedium’s dashboards, core use cases, and how teams use the product."
+sidebarTitle: "Product Tour"
+icon: "book"
---
-
### 1. Overview of SourceMedium
-SourceMedium is a trusted data and analytics product for high growth omni-channel, digital first brands.
+SourceMedium is a data and analytics product for omni-channel, digital-first brands.
-We help our customers create a singular view of their operations by centralizing data from 50+ platforms ([see our current list of available integrations](/data-inputs/platform-integration-instructions/all-available-integrations)). Our experience launching and growing eCommerce brands and servicing hundreds more ensures that every report & visualization is accurate, relevant, insightful, and actionable
+We help teams create a single view of their operations by centralizing data across e-commerce, marketing, subscription, and operations platforms ([see our current list of available integrations](/data-inputs/platform-integration-instructions/all-available-integrations)).
-We are currently working with some of the fastest growing omnichannel eCommerce brands with annual run rate GMVs ranging from $10 - $100 million.
+SourceMedium is used by brands at a range of growth stages and data maturity levels.
### 2. A Turnkey Analytics Hub
SourceMedium's analytics dashboards have been carefully curated to surface the most important insights for your business. All users will have access to a range of modules that include:
-- **Executive Summaries -** over 100+ KPIs on one dashboard, ranging from revenue and order level details to active subscribers counts (if applicable) and YoY tracking.
+- **Executive Summaries -** a broad set of KPIs in one dashboard, ranging from revenue and order details to subscriber metrics (when applicable) and YoY tracking.
- **Acquisition and Retention -** various dashboards covering marketing performance on major ad channels (Meta, Google, Snap, TikTok, among others), email marketing, influencer tracking, and customer lifetime value and repurchase analyses.
- **Deep Dives** - our most powerful dashboards provide your team deeper insights into customers' first and last order behavior, order-level purchasing patterns and sales, and individual product performance.
@@ -46,7 +48,7 @@ While there are plenty of data visualization and reporting solutions out in the
- Ensure that your data is clean and accurate in order to understand your **true blended CAC and ROAS** across your entire digital marketing efforts
- Help to understand **retention rates, lifetime value (LTV), and repurchasing behaviors** of your most valuable customers
-- Accurately attribute each order with the proper UTM tracking parameters – **SourceMedium can routinely attribute UTMs to up to 10-30% more orders than Google Analytics**
+- Attribute orders using multiple UTM sources (Shopify visits, landing site, order notes, website events, GA4) and a clear selection hierarchy (see [Attribution Source Hierarchy](/data-transformations/attribution-source-hierarchy))
- Understand your **product performance** on a product or SKU level, as well as products most commonly purchased together.
- Get a clear understanding of your **influencer performance and ROI** with a custom influencer tracking solution
- Continue to grow our data connection footprint to meet your **omni-channel needs** with insightful and actionable data
@@ -89,4 +91,4 @@ Our CPAs capture spend from all marketing channels for a true calculation of ble

-Our proprietary customer data model has the widest coverage for lack-click UTM attribution channels which we supplement with other attribution points such as zero party data.
\ No newline at end of file
+Our proprietary customer data model has the widest coverage for lack-click UTM attribution channels which we supplement with other attribution points such as zero party data.
diff --git a/onboarding/getting-started/level-1-data-checklist.mdx b/onboarding/getting-started/level-1-data-checklist.mdx
index 203117a..2049c4e 100644
--- a/onboarding/getting-started/level-1-data-checklist.mdx
+++ b/onboarding/getting-started/level-1-data-checklist.mdx
@@ -24,11 +24,11 @@ recommended best practices to enhance your data setup and supercharge your insig
🤔 [Fill out the Top 3 analytical questions](https://share.hsforms.com/12YlIhvZKSVysSYvnP1mZ7w4j6uk) — Let us know how we can guide you
-{/* 💭 [Check out our most common analytical questions](/source-medium-university/getting-started/thinking-analytically/common-analytical-questions) — Under construction, but our CSAs can always walk you through any of these analytical questions */}
+💭 [Check out our most common analytical questions](/onboarding/getting-started/thinking-analytically/common-analytical-questions) — Get ideas for analyses to run with your SourceMedium data
#### Data Cleaning 🧹
-0️⃣ [SM's "Exclude \$0 orders" feature](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-\$0-feature) — Improve the accuracy of your acquisition metrics
+0️⃣ [SM's "Exclude $0 orders" feature](/help-center/faq/dashboard-functionality-faqs/what-is-exclude-zero-dollar-feature) — Improve the accuracy of your acquisition metrics
📊 [Separate sales into sub-channels](/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels) — Group orders for quick custom analyses
@@ -38,4 +38,4 @@ recommended best practices to enhance your data setup and supercharge your insig
---
-- [**Level 2**](/onboarding/getting-started/level-2-data-checklist): Advanced use cases with SourceMedium (including insights and enablement)
\ No newline at end of file
+- [**Level 2**](/onboarding/getting-started/level-2-data-checklist): Advanced use cases with SourceMedium (including insights and enablement)
diff --git a/onboarding/getting-started/level-2-data-checklist.mdx b/onboarding/getting-started/level-2-data-checklist.mdx
index da674b3..8154967 100644
--- a/onboarding/getting-started/level-2-data-checklist.mdx
+++ b/onboarding/getting-started/level-2-data-checklist.mdx
@@ -36,12 +36,12 @@ recommended best practices to enhance your data setup and supercharge your insig
Stay tuned for more checklists, and get ready to unlock the power of your data 🔐
-- **Level 3** (coming soon!): Deep dive customer, order, and product level analysis
+- **Level 3**: Deep dive customer, order, and product level analysis
### **Recap**
1️⃣ [**Level 1 Checklist**](/onboarding/getting-started/level-1-data-checklist): Building the foundation
-{/* 💭 [Check out our most common analytical questions](/source-medium-university/getting-started/thinking-analytically/common-analytical-questions) */}
+💭 [Check out our most common analytical questions](/onboarding/getting-started/thinking-analytically/common-analytical-questions)
🥶 [SourceMedium Cold Start Guide](/help-center/faq/cold-start-guide-home)
diff --git a/onboarding/getting-started/level-3-data-checklist.mdx b/onboarding/getting-started/level-3-data-checklist.mdx
index 3dacd69..b38cc5f 100644
--- a/onboarding/getting-started/level-3-data-checklist.mdx
+++ b/onboarding/getting-started/level-3-data-checklist.mdx
@@ -1,6 +1,7 @@
---
title: "Level 3 Data Checklist"
description: "Follow this Level 3 checklist with tips and tricks to improve your data setup and use of SourceMedium"
+icon: "book"
---
@@ -31,6 +32,6 @@ As always, if you have any questions about this checklist, please reach out to u
2️⃣ [**Level 2 Checklist**](/onboarding/getting-started/level-2-data-checklist): Advanced use cases with SourceMedium
-{/* 💭 [Check out our most common analytical questions](/source-medium-university/getting-started/thinking-analytically/common-analytical-questions) */}
+💭 [Check out our most common analytical questions](/onboarding/getting-started/thinking-analytically/common-analytical-questions)
-🥶 [SourceMedium Cold Start Guide](/help-center/faq/cold-start-guide-home)
\ No newline at end of file
+🥶 [SourceMedium Cold Start Guide](/help-center/faq/cold-start-guide-home)
diff --git a/onboarding/getting-started/thinking-analytically/common-analytical-questions.mdx b/onboarding/getting-started/thinking-analytically/common-analytical-questions.mdx
index 4692c97..65c743d 100644
--- a/onboarding/getting-started/thinking-analytically/common-analytical-questions.mdx
+++ b/onboarding/getting-started/thinking-analytically/common-analytical-questions.mdx
@@ -1,6 +1,8 @@
---
title: "The Most Asked Analytical Questions"
+description: "Onboarding guide: The Most Asked Analytical Questions."
sidebarTitle: "Top Analytical Questions"
+icon: "book"
---
## Looking for inspiration? Below are some of our most commonly asked analytical questions!
@@ -41,4 +43,4 @@ Let us know what insights you would like to unlock.
- What is the typical subscriber journey?
- How much of my total revenue is driven by subscriptions?
-- How much of our current revenue is driven by historical subscriber cohorts?
\ No newline at end of file
+- How much of our current revenue is driven by historical subscriber cohorts?
diff --git a/onboarding/getting-started/thinking-analytically/how-analytical-questions-are-key.mdx b/onboarding/getting-started/thinking-analytically/how-analytical-questions-are-key.mdx
index f42fdfa..b1679d3 100644
--- a/onboarding/getting-started/thinking-analytically/how-analytical-questions-are-key.mdx
+++ b/onboarding/getting-started/thinking-analytically/how-analytical-questions-are-key.mdx
@@ -1,10 +1,12 @@
---
title: "How analytical questions are key to developing a data-driven culture"
+description: "Onboarding guide: How analytical questions are key to developing a data-driven culture."
sidebarTitle: "The Importance of Analytical Questions"
+icon: "book"
---

-Specific questions unlock the power of Source Medium dashboards — the more specific the question, the more actionable the insight! 🚀
+Specific questions unlock the power of SourceMedium dashboards — the more specific the question, the more actionable the insight! 🚀
---
diff --git a/onboarding/getting-started/why-source-medium.mdx b/onboarding/getting-started/why-source-medium.mdx
index 28af82a..1d9ade8 100644
--- a/onboarding/getting-started/why-source-medium.mdx
+++ b/onboarding/getting-started/why-source-medium.mdx
@@ -1,13 +1,14 @@
---
title: "Why SourceMedium?"
+description: "Onboarding guide: Why SourceMedium?."
+icon: "book"
---
-
## Do you have the right tools to build a data driven culture?
SourceMedium allows you to easily analyze `siloed data` across eCommerce, retail, marketing, and operations platforms — all in one place.

-We save time and resources spent inmanual spreadsheets and expensive, hard to manage internal data setups. Through a simple plug and play onboarding, we take care of all your data needs so that you're left with a powerful analytics tool for more actionable insights.
+We save time and resources spent in manual spreadsheets and hard-to-maintain internal data setups. Through a plug-and-play onboarding, we take care of data integration and standardization so you’re left with analytics you can trust.

@@ -17,21 +18,21 @@ We save time and resources spent inmanual spreadsheets and expensive, hard to ma
Troublesome Google Analytics and UTM tracking? Are you properly segmenting your spend among sales channels and international markets? How about excluding $0 revenue orders like influencer samples?
-We won't rest until yournumbers and metrics are completely accurate and reliable.
+We won't rest until your numbers and metrics are accurate and reliable.
✅ **We automate your manual work**
Spending countless hours with error-prone manual data pulls, pivot tables and visualizations? We've been there. Our customers save up to 20+ hours per week by replacing unreliable data management tools and processes.
-✅ **We have the #1 last click Source/Medium attribution coverage**
+✅ **We prioritize accurate last-click attribution**
-SourceMedium can attribute UTMs on up to 30% more orders than Google Analytics. We further enrich our attribution through touch points like post-purchase survey data.
+SourceMedium uses multiple attribution signals (including UTMs and other touchpoints) and a clear source selection hierarchy to maximize coverage and consistency.
✅ **We're built for omni-channel businesses**
Our rapidly expanding list of integrations include curated eCommerce, marketing, and operations channels that are interconnected so you can leverage your data for more advanced, cross-channel insights.
-**For our better-for-you CPG customers** will be soon launching retail coverage through our exclusive partnership with SPINS, the leader in wellness-retail POS data
+Retail and offline coverage varies by customer and setup — ask your SourceMedium team if you need retail support.

@@ -44,15 +45,17 @@ Our rapidly expanding list of integrations include curated eCommerce, marketing,
🧊 **Will help uncover deep insights on your business**
-Our dashboards are flexible, and like an iceberg will uncover more of our deep data layer as new use cases emerge. We stitch together multiple data sources to analyze customers, orders, and products at a more granular level so you can run meaningful analysis vs. just high level reporting.
+Our dashboards are flexible, and like an iceberg will uncover more of our deep data layer as new use cases emerge. We **intelligently aggregate multiple first-party data sources** to analyze customers, orders, and products at a more granular level so you can run meaningful analysis vs. just high level reporting.

-A source of truth across the organization - from customized CEO reports to Order Deep Dives
-A source of truth across the organization - from customized CEO reports to Order Deep Dives
+A source of truth across the organization—from customized CEO reports to Order Deep Dives.
+
+**Intelligent Data Aggregation**: We merge signals from all your platforms (e.g., Shopify + GA4 + Surveys) to create the highest quality dataset possible. More data sources and better capture mean better outputs for your business.
+
🧑🍳 We offer a Michelin star customer experience
-We have shared slack channels with 90%+ of our customers for direct and fast communication. Our dedicated customer solutions analysts help to demystify complex data problems and to pull out deep analytical insights from our product.
+We use shared Slack channels for direct, fast communication. Our Customer Solutions Analysts help demystify complex data problems and pull out actionable insights.
We are a one-stop shop for data solutions
🔧 Customizable executive and cross-functional dashboards
@@ -72,6 +75,4 @@ We are a one-stop shop for data solutions

-_🪄 Visit sourcemedium.com to sign up for a demo and to access our 7-day free trial_
-
-
+_🪄 Visit sourcemedium.com to request a demo._
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 0000000..603edab
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,4 @@
+[pytest]
+markers =
+ live: hits production docs site
+
diff --git a/scripts/docs_column_accuracy.py b/scripts/docs_column_accuracy.py
new file mode 100644
index 0000000..7d9ab20
--- /dev/null
+++ b/scripts/docs_column_accuracy.py
@@ -0,0 +1,292 @@
+#!/usr/bin/env python3
+"""
+Validate table/column references in docs SQL examples against schema docs (dbt YAML snapshots).
+
+Why this exists:
+- Drift is most painful in "how to query" pages where examples reference columns that
+ may be renamed in dbt (rename_column_map_all).
+- The canonical exposed column list is already present in this repo under
+ data-activation/data-tables/sm_transformed_v2/*.mdx as a fenced ```yaml block.
+
+This script:
+1) Parses those schema pages to build a map of table -> exposed column names.
+2) Validates fenced ```sql examples that reference `sm_transformed_v2` use real columns.
+
+Usage:
+ python3 scripts/docs_column_accuracy.py
+"""
+
+from __future__ import annotations
+
+import re
+import sys
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Iterable
+
+
+REPO_ROOT = Path(__file__).resolve().parents[1]
+SCHEMA_DOCS_DIRS: tuple[tuple[str, Path], ...] = (
+ (
+ "sm_transformed_v2",
+ REPO_ROOT / "data-activation" / "data-tables" / "sm_transformed_v2",
+ ),
+ (
+ "sm_experimental",
+ REPO_ROOT / "data-activation" / "data-tables" / "sm_experimental",
+ ),
+ ("sm_metadata", REPO_ROOT / "data-activation" / "data-tables" / "sm_metadata"),
+)
+
+
+YAML_BLOCK_RE = re.compile(r"```yaml\s*\n(.*?)\n```", re.DOTALL)
+YAML_NAME_RE = re.compile(r"^\s*-\s*name:\s*([A-Za-z0-9_]+)\s*$", re.MULTILINE)
+SQL_BLOCK_RE = re.compile(r"```sql\s*\n(.*?)\n```", re.DOTALL | re.IGNORECASE)
+
+# Table refs in example SQL blocks typically look like:
+# FROM `your_project.sm_transformed_v2.obt_orders` o
+# FROM `your_project.sm_metadata.dim_data_dictionary` d
+TABLE_REF_RE = re.compile(
+ r"`[^`]*?\.(sm_transformed_v2|sm_experimental|sm_metadata)\.([A-Za-z0-9_]+)`(?:\s+(?:AS\s+)?([A-Za-z_][A-Za-z0-9_]*))?",
+ re.IGNORECASE,
+)
+QUALIFIED_COL_RE = re.compile(r"\b([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)\b")
+# Avoid matching tokens that are clearly the RHS of a dotted identifier (e.g., "dimension_value.email_sms")
+# or segments inside a dotted table path (e.g., "`your_project.sm_experimental.table`").
+UNQUALIFIED_IDENT_RE = re.compile(r"(? Iterable[Path]:
+ if not root.exists():
+ return []
+ return sorted(root.rglob("*.mdx"))
+
+
+def is_excluded_path(path: Path) -> bool:
+ # Exclude internal/authoring scratch pads and non-page content.
+ if any(part.startswith(".") for part in path.parts):
+ return True
+ if path.parts and path.parts[0] in {"snippets", "yaml-files", "internal"}:
+ return True
+ return False
+
+
+def extract_yaml_block(text: str) -> str | None:
+ m = YAML_BLOCK_RE.search(text)
+ if not m:
+ return None
+ return m.group(1)
+
+
+def build_table_columns_from_schema_docs() -> dict[str, set[str]]:
+ table_to_columns: dict[str, set[str]] = {}
+ for dataset_name, schema_dir in SCHEMA_DOCS_DIRS:
+ for path in iter_mdx_files(schema_dir):
+ table_name = path.stem
+ text = path.read_text(encoding="utf-8", errors="ignore")
+ yaml_block = extract_yaml_block(text)
+ if not yaml_block:
+ continue
+ names = YAML_NAME_RE.findall(yaml_block)
+ if not names:
+ continue
+ # First "- name:" is the model name itself; the remainder are column names.
+ if names and names[0] == table_name:
+ names = names[1:]
+ cols = {n for n in names if n != table_name}
+ if cols:
+ table_to_columns[f"{dataset_name}.{table_name}"] = cols
+ return table_to_columns
+
+
+def extract_sql_blocks(text: str) -> list[str]:
+ return [m.group(1) for m in SQL_BLOCK_RE.finditer(text)]
+
+
+def normalize_sql(sql: str) -> str:
+ # Strip line comments and collapse whitespace.
+ sql = re.sub(r"--.*?$", "", sql, flags=re.M)
+ sql = re.sub(r"/\*.*?\*/", "", sql, flags=re.S)
+ # Strip quoted string literals so placeholders don't look like identifiers.
+ sql = re.sub(r"'([^'\\]|\\.)*'", "''", sql)
+ sql = re.sub(r'"([^"\\]|\\.)*"', '""', sql)
+ return sql
+
+
+def validate_sql_blocks(
+ *,
+ path: Path,
+ text: str,
+ table_to_columns: dict[str, set[str]],
+) -> list[Issue]:
+ issues: list[Issue] = []
+ for sql in extract_sql_blocks(text):
+ sql_norm = normalize_sql(sql)
+ alias_to_table: dict[str, str] = {}
+ referenced_tables: set[str] = set()
+
+ for dataset, table, alias in TABLE_REF_RE.findall(sql_norm):
+ dataset = dataset.lower()
+ table_key = f"{dataset}.{table}"
+ referenced_tables.add(table_key)
+ if alias:
+ alias_to_table[alias] = table_key
+ alias_to_table.setdefault(table, table_key)
+
+ known_tables = {t for t in referenced_tables if t in table_to_columns}
+
+ # 1) Qualified column references: alias.column
+ for qualifier, col in QUALIFIED_COL_RE.findall(sql_norm):
+ if qualifier not in alias_to_table:
+ continue
+ table = alias_to_table[qualifier]
+ if table not in table_to_columns:
+ continue
+ if col not in table_to_columns[table]:
+ issues.append(
+ Issue(
+ path,
+ f"unknown column `{qualifier}.{col}` for table `{table}` in sql block",
+ )
+ )
+
+ # 2) Unqualified identifiers: validate only when the SQL references exactly one known table.
+ if len(known_tables) != 1:
+ continue
+ (single_table,) = tuple(known_tables)
+ known_cols = table_to_columns[single_table]
+
+ aliases = set(AS_ALIAS_RE.findall(sql_norm))
+ ctes = set(CTE_NAME_RE.findall(sql_norm))
+ ignore = SQL_IGNORE_WORDS | SQL_IGNORE_FUNCTIONS | set(alias_to_table.keys()) | aliases | ctes
+ ignore |= {single_table, "your_project", "sm_transformed_v2"}
+
+ for ident in UNQUALIFIED_IDENT_RE.findall(sql_norm):
+ if ident in ignore:
+ continue
+ if ident not in known_cols:
+ issues.append(Issue(path, f"unknown column `{ident}` for table `{single_table}` in sql block"))
+
+ return issues
+
+
+def main() -> int:
+ table_to_columns = build_table_columns_from_schema_docs()
+ if not table_to_columns:
+ print(f"[INFO] No schema docs found under {SCHEMA_DOCS_DIR} (skipping accuracy checks).")
+ return 0
+
+ issues: list[Issue] = []
+ for path in iter_mdx_files(REPO_ROOT):
+ rel = path.relative_to(REPO_ROOT)
+ if is_excluded_path(rel):
+ continue
+ text = path.read_text(encoding="utf-8", errors="ignore")
+ if "```sql" not in text.lower():
+ continue
+ issues.extend(validate_sql_blocks(path=path, text=text, table_to_columns=table_to_columns))
+
+ if issues:
+ print(f"[ERROR] Column accuracy check failed with {len(issues)} issue(s):")
+ for issue in issues[:100]:
+ rel = issue.path.relative_to(REPO_ROOT)
+ print(f" - {rel}: {issue.message}")
+ if len(issues) > 100:
+ print(f" ... and {len(issues) - 100} more")
+ return 1
+
+ print("[OK] Column accuracy check passed")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/scripts/docs_inventory.py b/scripts/docs_inventory.py
new file mode 100644
index 0000000..fb904d2
--- /dev/null
+++ b/scripts/docs_inventory.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python3
+"""
+Docs inventory checks for the Mintlify site.
+
+Checks:
+1) Metadata: every page MDX has non-empty title/description/icon in frontmatter
+2) Orphans: every page MDX is referenced in docs.json navigation (with allowlisted exceptions)
+
+Usage:
+ python3 scripts/docs_inventory.py
+
+Exit codes:
+ 0 = OK
+ 1 = issues found
+"""
+
+from __future__ import annotations
+
+import json
+import re
+import sys
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any, Iterable
+
+
+REPO_ROOT = Path(__file__).resolve().parents[1]
+DOCS_JSON = REPO_ROOT / "docs.json"
+
+PAGE_DIR_EXCLUDES = {"snippets", "yaml-files"}
+ALLOW_ORPHAN_PATTERNS = [
+ r"/hidden-", # hidden utility pages
+ r"^tenants/", # hidden tenant-specific pages
+ r"template", # authoring templates
+]
+
+
+@dataclass(frozen=True)
+class Frontmatter:
+ title: str | None
+ description: str | None
+ icon: str | None
+
+
+def normalize_title(title: str) -> str:
+ norm = title.strip().lower()
+ norm = re.sub(r"""[?!\.:,'"`“”’()\[\]{}]+""", "", norm)
+ norm = re.sub(r"\s+", " ", norm)
+ return norm
+
+
+def is_excluded_path(path: Path) -> bool:
+ if any(part.startswith(".") for part in path.parts):
+ return True
+ if path.parts and path.parts[0] in PAGE_DIR_EXCLUDES:
+ return True
+ return False
+
+
+def iter_page_mdx_files() -> Iterable[Path]:
+ for path in REPO_ROOT.rglob("*.mdx"):
+ rel = path.relative_to(REPO_ROOT)
+ if is_excluded_path(rel):
+ continue
+ yield path
+
+
+def mdx_ref_from_path(path: Path) -> str:
+ rel = path.relative_to(REPO_ROOT).with_suffix("")
+ return str(rel).replace("\\", "/")
+
+
+def extract_page_refs_from_docs_json(obj: Any, refs: set[str]) -> None:
+ """
+ Extract docs.json navigation references (paths without .mdx).
+
+ Important: only traverse the navigation structure to avoid accidentally
+ collecting arbitrary strings (titles, descriptions, etc.).
+ """
+ if isinstance(obj, str):
+ if obj.startswith("http") or obj.startswith("#"):
+ return
+ refs.add(obj.lstrip("/"))
+ return
+
+ if isinstance(obj, list):
+ for item in obj:
+ extract_page_refs_from_docs_json(item, refs)
+ return
+
+ if isinstance(obj, dict):
+ for key in ("tabs", "pages", "navigation", "groups"):
+ if key in obj:
+ extract_page_refs_from_docs_json(obj[key], refs)
+
+
+def load_docs_json_refs() -> set[str]:
+ data = json.loads(DOCS_JSON.read_text(encoding="utf-8"))
+ refs: set[str] = set()
+ extract_page_refs_from_docs_json(data, refs)
+ return refs
+
+
+def parse_frontmatter(text: str) -> Frontmatter | None:
+ if not text.startswith("---"):
+ return None
+ parts = text.split("---", 2)
+ if len(parts) < 3:
+ return None
+
+ fm = parts[1]
+
+ def get(key: str) -> str | None:
+ m = re.search(rf"^{re.escape(key)}:\s*(.+?)\s*$", fm, flags=re.M)
+ if not m:
+ return None
+ raw = m.group(1).strip()
+ # strip quotes
+ if (raw.startswith('"') and raw.endswith('"')) or (raw.startswith("'") and raw.endswith("'")):
+ raw = raw[1:-1].strip()
+ return raw or None
+
+ return Frontmatter(title=get("title"), description=get("description"), icon=get("icon"))
+
+
+def is_allowed_orphan(ref: str) -> bool:
+ for pat in ALLOW_ORPHAN_PATTERNS:
+ if re.search(pat, ref, flags=re.IGNORECASE):
+ return True
+ return False
+
+
+def main() -> int:
+ if not DOCS_JSON.exists():
+ print(f"[ERROR] docs.json not found at {DOCS_JSON}")
+ return 1
+
+ docs_refs = load_docs_json_refs()
+ page_files = list(iter_page_mdx_files())
+ page_refs = {mdx_ref_from_path(p) for p in page_files}
+
+ # Metadata check
+ metadata_issues: list[str] = []
+ frontmatters: dict[Path, Frontmatter] = {}
+ for p in page_files:
+ text = p.read_text(encoding="utf-8", errors="ignore")
+ fm = parse_frontmatter(text)
+ if fm is None:
+ metadata_issues.append(f"{p.relative_to(REPO_ROOT)}: missing/invalid frontmatter")
+ continue
+ frontmatters[p] = fm
+ if not fm.title:
+ metadata_issues.append(f"{p.relative_to(REPO_ROOT)}: missing title")
+ if not fm.description:
+ metadata_issues.append(f"{p.relative_to(REPO_ROOT)}: missing description")
+ elif re.match(r"^Learn about .+ in SourceMedium\.$", fm.description):
+ metadata_issues.append(f"{p.relative_to(REPO_ROOT)}: generic description (replace with a real summary)")
+ if not fm.icon:
+ metadata_issues.append(f"{p.relative_to(REPO_ROOT)}: missing icon")
+
+ # Duplicate title check (published pages only)
+ normalized_title_to_paths: dict[str, list[Path]] = {}
+ for p, fm in frontmatters.items():
+ ref = mdx_ref_from_path(p)
+ if is_allowed_orphan(ref):
+ continue
+ if not fm.title:
+ continue
+ normalized = normalize_title(fm.title)
+ normalized_title_to_paths.setdefault(normalized, []).append(p)
+
+ title_dupes = sorted(
+ (k, v) for k, v in normalized_title_to_paths.items() if len(v) > 1
+ )
+
+ # Orphans check
+ orphan_refs = sorted(r for r in (page_refs - docs_refs) if not is_allowed_orphan(r))
+ ignored_orphans = sorted(r for r in (page_refs - docs_refs) if is_allowed_orphan(r))
+
+ had_issues = False
+
+ if metadata_issues:
+ had_issues = True
+ print(f"[ERROR] Missing metadata in {len(metadata_issues)} page(s):")
+ for line in metadata_issues[:50]:
+ print(f" - {line}")
+ if len(metadata_issues) > 50:
+ print(f" ... and {len(metadata_issues) - 50} more")
+
+ if title_dupes:
+ had_issues = True
+ print(f"[ERROR] Duplicate page titles detected: {len(title_dupes)}")
+ for normalized, paths in title_dupes[:50]:
+ titles = sorted({frontmatters[p].title for p in paths if frontmatters[p].title})
+ display_title = titles[0] if titles else normalized
+ print(f" - {display_title}")
+ for p in sorted(paths):
+ print(f" - {p.relative_to(REPO_ROOT)}")
+ if len(title_dupes) > 50:
+ print(f" ... and {len(title_dupes) - 50} more")
+
+ if orphan_refs:
+ had_issues = True
+ print(f"[ERROR] Orphan pages (not in docs.json): {len(orphan_refs)}")
+ for r in orphan_refs[:50]:
+ print(f" - {r}")
+ if len(orphan_refs) > 50:
+ print(f" ... and {len(orphan_refs) - 50} more")
+
+ if ignored_orphans:
+ print(f"[INFO] Ignored orphans (allowed): {len(ignored_orphans)}")
+ for r in ignored_orphans[:20]:
+ print(f" - {r}")
+ if len(ignored_orphans) > 20:
+ print(f" ... and {len(ignored_orphans) - 20} more")
+
+ if not had_issues:
+ print("[OK] Docs inventory checks passed")
+ return 1 if had_issues else 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/scripts/docs_placeholder_lint.py b/scripts/docs_placeholder_lint.py
new file mode 100644
index 0000000..984639c
--- /dev/null
+++ b/scripts/docs_placeholder_lint.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python3
+"""
+Lightweight placeholder-language lint for the Mintlify docs repo.
+
+Goals:
+- Prevent "placeholder" phrases from creeping into published docs.
+- Keep the rules intentionally small and explicit.
+
+Usage:
+ python3 scripts/docs_placeholder_lint.py
+"""
+
+from __future__ import annotations
+
+import re
+import sys
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Iterable
+
+
+REPO_ROOT = Path(__file__).resolve().parents[1]
+
+DIR_EXCLUDES = {"snippets", "yaml-files", "internal"}
+
+
+@dataclass(frozen=True)
+class Pattern:
+ name: str
+ regex: re.Pattern[str]
+
+
+PATTERNS: list[Pattern] = [
+ Pattern("coming_soon", re.compile(r"\bcoming soon\b", re.IGNORECASE)),
+ Pattern("under_construction", re.compile(r"\bunder construction\b", re.IGNORECASE)),
+ Pattern("todo", re.compile(r"\bTODO\b")),
+ Pattern("tbd", re.compile(r"\bTBD\b")),
+ Pattern("lorem_ipsum", re.compile(r"\blorem\b|\bipsum\b", re.IGNORECASE)),
+ Pattern("tablestakes_typo", re.compile(r"\btablestakes\b", re.IGNORECASE)),
+]
+
+ALLOWLIST: dict[str, set[Path]] = {
+ # Product roadmap legitimately uses status labels like "Coming Soon".
+ "coming_soon": {Path("ai-analyst/roadmap.mdx")},
+}
+
+
+def is_excluded(rel: Path) -> bool:
+ if any(part.startswith(".") for part in rel.parts):
+ return True
+ if rel.parts and rel.parts[0] in DIR_EXCLUDES:
+ return True
+ return False
+
+
+def iter_doc_files() -> Iterable[Path]:
+ for ext in ("*.mdx", "*.md"):
+ for path in REPO_ROOT.rglob(ext):
+ rel = path.relative_to(REPO_ROOT)
+ if is_excluded(rel):
+ continue
+ yield path
+
+
+def main() -> int:
+ matches: list[str] = []
+ for path in iter_doc_files():
+ try:
+ lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
+ except OSError:
+ continue
+ for i, line in enumerate(lines, start=1):
+ for pattern in PATTERNS:
+ if pattern.regex.search(line):
+ rel = path.relative_to(REPO_ROOT)
+ if rel in ALLOWLIST.get(pattern.name, set()):
+ continue
+ matches.append(f"{rel}:{i}: {pattern.name}")
+
+ if matches:
+ print(f"[ERROR] Placeholder language found in {len(matches)} location(s):")
+ for m in matches[:100]:
+ print(f" - {m}")
+ if len(matches) > 100:
+ print(f" ... and {len(matches) - 100} more")
+ return 1
+
+ print("[OK] Placeholder lint passed")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/scripts/ragie_sync.py b/scripts/ragie_sync.py
new file mode 100755
index 0000000..78afee2
--- /dev/null
+++ b/scripts/ragie_sync.py
@@ -0,0 +1,1544 @@
+#!/usr/bin/env python3
+"""
+Sync SourceMedium docs into Ragie with strict partition scoping.
+
+Behavior:
+- Discovers published docs from docs.json
+- Normalizes MDX/Markdown into retrieval text
+- Upserts via external_id in a target partition
+- Deletes stale docs in that partition
+- Polls ingestion status for changed docs
+
+Usage examples:
+ python3 scripts/ragie_sync.py --partition shared_docs
+ python3 scripts/ragie_sync.py --partition tenant_acme --doc-ref onboarding/getting-started/intro-to-sm --dry-run
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import os
+import re
+import time
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any
+from urllib.error import HTTPError, URLError
+from urllib.parse import urlencode
+from urllib.request import Request, urlopen
+
+
+REPO_ROOT = Path(__file__).resolve().parents[1]
+DOCS_JSON = REPO_ROOT / "docs.json"
+ENV_FILE = REPO_ROOT / ".env"
+
+MANAGED_METADATA_KEYS = {
+ "source",
+ "repo",
+ "docs_ref",
+ "url_path",
+ "url_full",
+ "title",
+ "description",
+ "content_hash",
+ "commit_sha",
+ "visibility",
+ "tenant_id",
+ "taxonomy_version",
+ "doc_domain",
+ "doc_subdomain",
+ "content_type",
+ "primary_surface",
+ "surfaces",
+ "topic_tags",
+ "frontmatter_tags",
+ "taxonomy_source",
+}
+
+TERMINAL_FAILURE_STATUSES = {"failed"}
+
+SURFACE_ENUM = [
+ "query_snippets",
+ "looker_studio",
+ "bigquery",
+ "managed_warehouse",
+ "dashboard",
+ "mta",
+ "configuration_sheet",
+ "general",
+]
+
+CONTENT_TYPE_ENUM = [
+ "query_snippet_library",
+ "data_table_reference",
+ "template_resource",
+ "dashboard_module_reference",
+ "managed_bi_guide",
+ "managed_warehouse_guide",
+ "faq",
+ "core_concept",
+ "analytics_tool_guide",
+ "onboarding_guide",
+ "integration_guide",
+ "mta_guide",
+ "general_doc",
+]
+
+DEFAULT_ENTITY_INSTRUCTION_PROMPT = (
+ "Extract analytics support entities from this SourceMedium documentation page. "
+ "Return a JSON object with: "
+ "surfaces (subset of allowed surfaces), "
+ "keywords (short lowercase topic tags), "
+ "table_names (BigQuery tables like obt_orders), "
+ "column_names (notable field names), "
+ "dashboard_modules (dashboard/module names), "
+ "integration_platforms (platform/vendor names). "
+ "Use empty arrays when unavailable."
+)
+
+
+def build_partition_metadata_schema() -> dict[str, Any]:
+ return {
+ "type": "object",
+ "additionalProperties": True,
+ "properties": {
+ "source": {
+ "type": "string",
+ "description": "Source marker for managed docs in this repository.",
+ },
+ "repo": {
+ "type": "string",
+ "description": "Repository identifier for managed docs.",
+ },
+ "docs_ref": {
+ "type": "string",
+ "description": "Canonical docs route/path without extension.",
+ },
+ "title": {
+ "type": "string",
+ "description": "Document title from frontmatter.",
+ },
+ "description": {
+ "type": "string",
+ "description": "Short document summary from frontmatter.",
+ },
+ "visibility": {
+ "type": "string",
+ "description": "Whether the doc is in a shared or tenant partition.",
+ "enum": ["shared", "tenant"],
+ },
+ "tenant_id": {
+ "type": "string",
+ "description": "Tenant identifier for tenant partitions.",
+ },
+ "content_type": {
+ "type": "string",
+ "description": "High-level document class derived from docs path.",
+ "enum": CONTENT_TYPE_ENUM,
+ },
+ "primary_surface": {
+ "type": "string",
+ "description": "Primary analytics surface for the doc.",
+ "enum": SURFACE_ENUM,
+ },
+ "surfaces": {
+ "type": "array",
+ "description": "All relevant analytics surfaces for the doc.",
+ "items": {"type": "string", "enum": SURFACE_ENUM},
+ "uniqueItems": True,
+ },
+ "topic_tags": {
+ "type": "array",
+ "description": "Normalized topic tags used for retrieval filtering.",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ "frontmatter_tags": {
+ "type": "array",
+ "description": "Optional frontmatter tags from markdown.",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ },
+ }
+
+
+def build_entity_schema() -> dict[str, Any]:
+ return {
+ "type": "object",
+ "additionalProperties": False,
+ "properties": {
+ "surfaces": {
+ "type": "array",
+ "items": {"type": "string", "enum": SURFACE_ENUM},
+ "uniqueItems": True,
+ },
+ "keywords": {
+ "type": "array",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ "table_names": {
+ "type": "array",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ "column_names": {
+ "type": "array",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ "dashboard_modules": {
+ "type": "array",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ "integration_platforms": {
+ "type": "array",
+ "items": {"type": "string"},
+ "uniqueItems": True,
+ },
+ },
+ "required": [
+ "surfaces",
+ "keywords",
+ "table_names",
+ "column_names",
+ "dashboard_modules",
+ "integration_platforms",
+ ],
+ }
+
+
+def default_partition_description(partition: str) -> str:
+ if partition == "shared_docs":
+ return (
+ "SourceMedium public documentation covering onboarding, integrations, "
+ "data transformations, managed BI/Looker Studio dashboards, BigQuery table "
+ "references, SQL query snippets, and help-center FAQs."
+ )
+ tenant_id = partition.removeprefix("tenant_")
+ return (
+ f"SourceMedium tenant documentation partition for '{tenant_id}'. Contains tenant-"
+ "scoped docs and the same core product documentation categories used for support retrieval."
+ )
+
+
+def default_entity_instruction_name(partition: str) -> str:
+ return f"sourcemedium-doc-entities-v1-{partition}"
+
+
+class SyncError(RuntimeError):
+ """Raised for sync/runtime failures."""
+
+
+@dataclass(frozen=True)
+class LocalDoc:
+ ref: str
+ path: Path
+ name: str
+ external_id: str
+ content: str
+ content_hash: str
+ metadata: dict[str, Any]
+
+
+def log(message: str) -> None:
+ print(message)
+
+
+def load_local_env(path: Path) -> None:
+ """Load .env into process env for local runs (without overriding existing env)."""
+ if not path.exists():
+ return
+
+ for raw_line in path.read_text(encoding="utf-8", errors="ignore").splitlines():
+ line = raw_line.strip()
+ if not line or line.startswith("#") or "=" not in line:
+ continue
+ key, value = line.split("=", 1)
+ key = key.strip()
+ value = value.strip().strip("\"'")
+ if key and key not in os.environ:
+ os.environ[key] = value
+
+
+def sanitize_partition(partition: str) -> str:
+ value = partition.strip().lower()
+ if not re.fullmatch(r"[a-z0-9_-]+", value):
+ raise SyncError(
+ f"Invalid partition '{partition}'. Partition must match ^[a-z0-9_-]+$."
+ )
+ return value
+
+
+def extract_page_refs(obj: Any, refs: set[str]) -> None:
+ if isinstance(obj, str):
+ if obj.startswith("http") or obj.startswith("#"):
+ return
+ refs.add(obj.lstrip("/"))
+ return
+
+ if isinstance(obj, list):
+ for item in obj:
+ extract_page_refs(item, refs)
+ return
+
+ if isinstance(obj, dict):
+ for key in ("tabs", "pages", "navigation", "groups"):
+ if key in obj:
+ extract_page_refs(obj[key], refs)
+
+
+def load_docs_refs() -> list[str]:
+ if not DOCS_JSON.exists():
+ raise SyncError(f"docs.json not found at {DOCS_JSON}")
+
+ raw = json.loads(DOCS_JSON.read_text(encoding="utf-8"))
+ refs: set[str] = set()
+ extract_page_refs(raw, refs)
+ return sorted(refs)
+
+
+def resolve_ref_path(ref: str) -> Path | None:
+ candidates = [
+ REPO_ROOT / f"{ref}.mdx",
+ REPO_ROOT / f"{ref}.md",
+ REPO_ROOT / ref / "index.mdx",
+ REPO_ROOT / ref / "index.md",
+ ]
+ for candidate in candidates:
+ if candidate.exists():
+ return candidate
+ return None
+
+
+def extract_tenant_slug_from_ref(ref: str) -> str | None:
+ normalized = ref.lstrip("/")
+ if not normalized.startswith("tenants/"):
+ return None
+
+ parts = normalized.split("/")
+ if len(parts) < 2:
+ return None
+
+ tenant_slug = parts[1].strip().lower()
+ if not re.fullmatch(r"[a-z0-9_-]+", tenant_slug):
+ return None
+ return tenant_slug
+
+
+def tenant_slug_from_partition(partition: str) -> str | None:
+ if not partition.startswith("tenant_"):
+ return None
+ tenant_slug = partition.removeprefix("tenant_").strip().lower()
+ if not tenant_slug:
+ return None
+ if not re.fullmatch(r"[a-z0-9_-]+", tenant_slug):
+ raise SyncError(
+ f"Invalid tenant partition '{partition}'. Expected tenant_ with slug matching ^[a-z0-9_-]+$."
+ )
+ return tenant_slug
+
+
+def discover_tenant_refs(tenant_slug: str) -> list[str]:
+ refs: set[str] = set()
+
+ top_level_candidates = [
+ REPO_ROOT / "tenants" / f"{tenant_slug}.mdx",
+ REPO_ROOT / "tenants" / f"{tenant_slug}.md",
+ ]
+ for path in top_level_candidates:
+ if path.exists():
+ rel = path.relative_to(REPO_ROOT).with_suffix("")
+ refs.add(str(rel).replace(os.sep, "/"))
+
+ tenant_dir = REPO_ROOT / "tenants" / tenant_slug
+ if tenant_dir.exists():
+ for path in tenant_dir.rglob("*"):
+ if not path.is_file():
+ continue
+ if path.suffix.lower() not in {".md", ".mdx"}:
+ continue
+ rel = path.relative_to(REPO_ROOT).with_suffix("")
+ refs.add(str(rel).replace(os.sep, "/"))
+
+ return sorted(refs)
+
+
+def scope_refs_for_partition(
+ *,
+ refs: list[str],
+ partition: str,
+) -> list[str]:
+ tenant_slug = tenant_slug_from_partition(partition)
+
+ if tenant_slug:
+ tenant_refs = discover_tenant_refs(tenant_slug)
+ if not tenant_refs:
+ log(f"[WARN] No tenant docs found under /tenants for tenant slug '{tenant_slug}'")
+ return tenant_refs
+
+ # Shared/non-tenant partitions must never include /tenants docs.
+ scoped = [ref for ref in refs if extract_tenant_slug_from_ref(ref) is None]
+ excluded = len(refs) - len(scoped)
+ if excluded:
+ log(f"[INFO] Excluded tenant docs from partition '{partition}': {excluded}")
+ return scoped
+
+
+def _strip_wrapping_quotes(value: str) -> str:
+ raw = value.strip()
+ if (raw.startswith('"') and raw.endswith('"')) or (raw.startswith("'") and raw.endswith("'")):
+ return raw[1:-1].strip()
+ return raw
+
+
+def _parse_inline_tags(raw_value: str) -> list[str]:
+ value = _strip_wrapping_quotes(raw_value)
+ if not value:
+ return []
+
+ if value.startswith("[") and value.endswith("]"):
+ inside = value[1:-1].strip()
+ if not inside:
+ return []
+ return [
+ _strip_wrapping_quotes(item).strip()
+ for item in inside.split(",")
+ if _strip_wrapping_quotes(item).strip()
+ ]
+
+ if "," in value:
+ return [
+ _strip_wrapping_quotes(item).strip()
+ for item in value.split(",")
+ if _strip_wrapping_quotes(item).strip()
+ ]
+
+ return [value]
+
+
+def parse_frontmatter(text: str) -> tuple[dict[str, Any], str]:
+ if not text.startswith("---"):
+ return {}, text
+
+ match = re.match(r"\A---\s*\n(.*?)\n---\s*\n?", text, flags=re.S)
+ if not match:
+ return {}, text
+
+ fm_raw = match.group(1)
+ body = text[match.end() :]
+
+ fm: dict[str, Any] = {}
+ lines = fm_raw.splitlines()
+ idx = 0
+ while idx < len(lines):
+ line = lines[idx]
+ m = re.match(r"^([A-Za-z0-9_]+):\s*(.*)$", line)
+ if not m:
+ idx += 1
+ continue
+
+ key = m.group(1).strip()
+ value = m.group(2).strip()
+
+ if key == "tags":
+ tags = _parse_inline_tags(value)
+ j = idx + 1
+ while j < len(lines):
+ tag_match = re.match(r"^\s*-\s+(.+)$", lines[j])
+ if not tag_match:
+ break
+ tag_value = _strip_wrapping_quotes(tag_match.group(1)).strip()
+ if tag_value:
+ tags.append(tag_value)
+ j += 1
+ fm[key] = tags
+ idx = j
+ continue
+
+ fm[key] = _strip_wrapping_quotes(value)
+ idx += 1
+
+ return fm, body
+
+
+def _strip_inline_tags(text: str) -> str:
+ text = re.sub(r"\{\s*/\*.*?\*/\s*\}", "", text, flags=re.S)
+ text = re.sub(r"?[A-Za-z][^>]*>", "", text)
+ text = re.sub(r"\{\s*[A-Za-z_][^{}\n]*\}", "", text)
+ return text
+
+
+def _collapse_spaces(text: str) -> str:
+ text = re.sub(r"[ \t]+", " ", text)
+ text = re.sub(r"\n{3,}", "\n\n", text)
+ return text.strip()
+
+
+def normalize_doc_text(raw_text: str, fallback_title: str) -> tuple[str, dict[str, Any]]:
+ frontmatter, body = parse_frontmatter(raw_text)
+
+ title = frontmatter.get("title") or fallback_title
+ description = frontmatter.get("description") or ""
+
+ body = body.replace("\r\n", "\n").replace("\r", "\n")
+
+ segments = re.split(r"(```[\s\S]*?```)", body)
+
+ callouts = {
+ "Info": "Info",
+ "Tip": "Tip",
+ "Note": "Note",
+ "Warning": "Warning",
+ }
+
+ processed: list[str] = []
+ for segment in segments:
+ if not segment:
+ continue
+ if segment.startswith("```"):
+ processed.append(segment)
+ continue
+
+ part = segment
+ part = re.sub(r"(?m)^\s*(import|export)\s+.+$", "", part)
+
+ for tag, label in callouts.items():
+ pattern = re.compile(rf"<{tag}\b[^>]*>([\s\S]*?){tag}>", flags=re.I)
+
+ def repl(match: re.Match[str], label: str = label) -> str:
+ inner = _strip_inline_tags(match.group(1))
+ inner = _collapse_spaces(inner)
+ return f"{label}: {inner}" if inner else label
+
+ part = pattern.sub(repl, part)
+
+ part = _strip_inline_tags(part)
+ processed.append(part)
+
+ normalized_body = "".join(processed)
+ normalized_body = _collapse_spaces(normalized_body)
+
+ preamble_parts = [f"# {title}"]
+ if description:
+ preamble_parts.append(description)
+
+ full_text = "\n\n".join(preamble_parts + [normalized_body]).strip() + "\n"
+
+ normalized_fm = {
+ "title": title,
+ "description": description,
+ "tags": frontmatter.get("tags", []),
+ }
+ return full_text, normalized_fm
+
+
+def sha256_text(text: str) -> str:
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()
+
+
+def _normalize_tag_value(tag: str) -> str:
+ return re.sub(r"\s+", "_", tag.strip().lower())
+
+
+def derive_taxonomy(
+ *,
+ ref: str,
+ title: str,
+ description: str,
+ frontmatter_tags: list[str] | None = None,
+) -> dict[str, Any]:
+ parts = ref.split("/")
+ doc_domain = parts[0] if parts else "unknown"
+ doc_subdomain = "/".join(parts[:2]) if len(parts) >= 2 else doc_domain
+
+ ref_lower = ref.lower()
+ text = f"{ref} {title} {description}".lower()
+
+ content_type = "general_doc"
+ if ref_lower == "data-activation/template-resources/sql-query-library":
+ content_type = "query_snippet_library"
+ elif ref_lower.startswith("data-activation/data-tables/"):
+ content_type = "data_table_reference"
+ elif ref_lower.startswith("data-activation/template-resources/"):
+ content_type = "template_resource"
+ elif ref_lower.startswith("data-activation/managed-bi-v1/modules/"):
+ content_type = "dashboard_module_reference"
+ elif ref_lower.startswith("data-activation/managed-bi-v1/"):
+ content_type = "managed_bi_guide"
+ elif ref_lower.startswith("data-activation/managed-data-warehouse/"):
+ content_type = "managed_warehouse_guide"
+ elif ref_lower.startswith("help-center/faq/"):
+ content_type = "faq"
+ elif ref_lower.startswith("help-center/core-concepts/"):
+ content_type = "core_concept"
+ elif ref_lower.startswith("onboarding/analytics-tools/"):
+ content_type = "analytics_tool_guide"
+ elif ref_lower.startswith("onboarding/getting-started/"):
+ content_type = "onboarding_guide"
+ elif ref_lower.startswith("data-inputs/platform-integration-instructions/"):
+ content_type = "integration_guide"
+ elif ref_lower.startswith("mta/"):
+ content_type = "mta_guide"
+
+ surfaces: set[str] = set()
+ if ref_lower.startswith("data-activation/managed-bi-v1/modules/"):
+ # Managed BI modules are dashboard-facing docs and should be routed as such.
+ surfaces.update({"dashboard", "looker_studio"})
+ elif ref_lower.startswith("data-activation/managed-bi-v1/"):
+ surfaces.add("dashboard")
+ if "looker studio" in text or "looker-studio" in text or "looker" in text:
+ surfaces.add("looker_studio")
+ if "bigquery" in text or "sql" in text or ref_lower.startswith("data-activation/data-tables/"):
+ surfaces.add("bigquery")
+ if "dashboard" in text:
+ surfaces.add("dashboard")
+ if "warehouse" in text or ref_lower.startswith("data-activation/managed-data-warehouse/"):
+ surfaces.add("managed_warehouse")
+ if ref_lower.startswith("mta/"):
+ surfaces.add("mta")
+ if "configuration-sheet" in ref_lower:
+ surfaces.add("configuration_sheet")
+
+ if not surfaces:
+ surfaces.add("general")
+
+ primary_surface_priority = [
+ "query_snippets",
+ "looker_studio",
+ "bigquery",
+ "managed_warehouse",
+ "dashboard",
+ "mta",
+ "configuration_sheet",
+ "general",
+ ]
+ primary_surface = "general"
+ for candidate in primary_surface_priority:
+ if candidate in surfaces:
+ primary_surface = candidate
+ break
+
+ frontmatter_tags = frontmatter_tags or []
+ normalized_frontmatter_tags = sorted(
+ {_normalize_tag_value(tag) for tag in frontmatter_tags if str(tag).strip()}
+ )
+
+ topic_tags: set[str] = {
+ f"domain:{doc_domain}",
+ f"subdomain:{doc_subdomain}",
+ f"content_type:{content_type}",
+ }
+ topic_tags.update(f"surface:{surface}" for surface in surfaces)
+ topic_tags.update(normalized_frontmatter_tags)
+
+ if ref_lower == "data-activation/template-resources/sql-query-library":
+ topic_tags.update({"query_snippets", "sql_examples", "analytics_queries"})
+ surfaces.add("query_snippets")
+ primary_surface = "query_snippets"
+
+ topic_tags.add(f"surface:{primary_surface}")
+
+ if "template" in ref_lower:
+ topic_tags.add("templates")
+ if content_type == "faq":
+ topic_tags.add("support")
+ if content_type.endswith("_guide"):
+ topic_tags.add("how_to")
+
+ return {
+ "taxonomy_version": "v1",
+ "doc_domain": doc_domain,
+ "doc_subdomain": doc_subdomain,
+ "content_type": content_type,
+ "primary_surface": primary_surface,
+ "surfaces": sorted(surfaces),
+ "topic_tags": sorted(topic_tags),
+ "frontmatter_tags": normalized_frontmatter_tags,
+ "taxonomy_source": "derived+frontmatter",
+ }
+
+
+class RagieClient:
+ def __init__(
+ self,
+ *,
+ api_key: str,
+ base_url: str,
+ timeout: int,
+ max_retries: int,
+ retry_base_delay: float,
+ ) -> None:
+ self.api_key = api_key
+ self.base_url = base_url.rstrip("/")
+ self.timeout = timeout
+ self.max_retries = max_retries
+ self.retry_base_delay = retry_base_delay
+
+ def _request(
+ self,
+ method: str,
+ path: str,
+ *,
+ query: dict[str, Any] | None = None,
+ partition: str | None = None,
+ json_body: dict[str, Any] | None = None,
+ ) -> Any:
+ if query:
+ clean_query = {k: v for k, v in query.items() if v is not None}
+ query_str = urlencode(clean_query)
+ url = f"{self.base_url}{path}?{query_str}" if query_str else f"{self.base_url}{path}"
+ else:
+ url = f"{self.base_url}{path}"
+
+ headers = {
+ "Authorization": f"Bearer {self.api_key}",
+ "Accept": "application/json",
+ }
+ if partition:
+ headers["partition"] = partition
+
+ payload: bytes | None = None
+ if json_body is not None:
+ payload = json.dumps(json_body).encode("utf-8")
+ headers["Content-Type"] = "application/json"
+
+ req = Request(url=url, data=payload, method=method, headers=headers)
+
+ for attempt in range(self.max_retries + 1):
+ try:
+ with urlopen(req, timeout=self.timeout) as response:
+ raw = response.read()
+ content_type = response.headers.get("Content-Type", "")
+ if "application/json" in content_type:
+ if not raw:
+ return {}
+ return json.loads(raw.decode("utf-8"))
+ return raw
+ except HTTPError as err:
+ status = err.code
+ raw = err.read().decode("utf-8", errors="ignore")
+ detail = raw
+ try:
+ parsed = json.loads(raw)
+ if isinstance(parsed, dict) and parsed.get("detail"):
+ detail = str(parsed["detail"])
+ except json.JSONDecodeError:
+ pass
+
+ if status in {429, 500, 502, 503, 504} and attempt < self.max_retries:
+ sleep_for = self.retry_base_delay * (2**attempt)
+ time.sleep(sleep_for)
+ continue
+
+ raise SyncError(f"Ragie API error {status} for {method} {path}: {detail}") from err
+ except URLError as err:
+ if attempt < self.max_retries:
+ sleep_for = self.retry_base_delay * (2**attempt)
+ time.sleep(sleep_for)
+ continue
+ raise SyncError(f"Network error for {method} {path}: {err}") from err
+
+ raise SyncError(f"Exhausted retries for {method} {path}")
+
+ def list_documents(self, partition: str) -> list[dict[str, Any]]:
+ docs: list[dict[str, Any]] = []
+ cursor: str | None = None
+
+ while True:
+ response = self._request(
+ "GET",
+ "/documents",
+ query={"page_size": 100, "cursor": cursor},
+ partition=partition,
+ )
+ page_docs = response.get("documents", [])
+ if not isinstance(page_docs, list):
+ raise SyncError("Unexpected /documents response shape: missing documents[]")
+ docs.extend(page_docs)
+
+ pagination = response.get("pagination", {}) or {}
+ cursor = pagination.get("next_cursor")
+ if not cursor:
+ break
+
+ return docs
+
+ def create_document_raw(
+ self,
+ *,
+ partition: str,
+ name: str,
+ external_id: str,
+ metadata: dict[str, Any],
+ data: str,
+ ) -> dict[str, Any]:
+ return self._request(
+ "POST",
+ "/documents/raw",
+ json_body={
+ "name": name,
+ "external_id": external_id,
+ "partition": partition,
+ "metadata": metadata,
+ "data": data,
+ },
+ )
+
+ def update_document_raw(self, *, partition: str, document_id: str, data: str) -> dict[str, Any]:
+ return self._request(
+ "PUT",
+ f"/documents/{document_id}/raw",
+ partition=partition,
+ json_body={"data": data},
+ )
+
+ def patch_document_metadata(
+ self,
+ *,
+ partition: str,
+ document_id: str,
+ metadata_patch: dict[str, Any],
+ ) -> dict[str, Any]:
+ return self._request(
+ "PATCH",
+ f"/documents/{document_id}/metadata",
+ partition=partition,
+ json_body={"metadata": metadata_patch, "async": False},
+ )
+
+ def get_document(self, *, partition: str, document_id: str) -> dict[str, Any]:
+ return self._request(
+ "GET",
+ f"/documents/{document_id}",
+ partition=partition,
+ )
+
+ def delete_document(self, *, partition: str, document_id: str, async_delete: bool) -> dict[str, Any]:
+ return self._request(
+ "DELETE",
+ f"/documents/{document_id}",
+ partition=partition,
+ query={"async": str(async_delete).lower()},
+ )
+
+ def list_partitions(self) -> list[dict[str, Any]]:
+ partitions: list[dict[str, Any]] = []
+ cursor: str | None = None
+ while True:
+ response = self._request(
+ "GET",
+ "/partitions",
+ query={"page_size": 100, "cursor": cursor},
+ )
+ page = response.get("partitions", [])
+ if not isinstance(page, list):
+ raise SyncError("Unexpected /partitions response shape: missing partitions[]")
+ partitions.extend(page)
+ pagination = response.get("pagination", {}) or {}
+ cursor = pagination.get("next_cursor")
+ if not cursor:
+ break
+ return partitions
+
+ def create_partition(
+ self,
+ *,
+ name: str,
+ description: str | None,
+ metadata_schema: dict[str, Any] | None,
+ ) -> dict[str, Any]:
+ payload: dict[str, Any] = {"name": name}
+ if description is not None:
+ payload["description"] = description
+ if metadata_schema is not None:
+ payload["metadata_schema"] = metadata_schema
+ return self._request("POST", "/partitions", json_body=payload)
+
+ def get_partition(self, *, partition_id: str) -> dict[str, Any]:
+ return self._request("GET", f"/partitions/{partition_id}")
+
+ def update_partition(
+ self,
+ *,
+ partition_id: str,
+ context_aware: bool | None = None,
+ description: str | None = None,
+ metadata_schema: dict[str, Any] | None = None,
+ ) -> dict[str, Any]:
+ payload: dict[str, Any] = {}
+ if context_aware is not None:
+ payload["context_aware"] = context_aware
+ if description is not None:
+ payload["description"] = description
+ if metadata_schema is not None:
+ payload["metadata_schema"] = metadata_schema
+ if not payload:
+ return self.get_partition(partition_id=partition_id)
+ return self._request("PATCH", f"/partitions/{partition_id}", json_body=payload)
+
+ def list_instructions(self) -> list[dict[str, Any]]:
+ response = self._request("GET", "/instructions")
+ if not isinstance(response, list):
+ raise SyncError("Unexpected /instructions response shape: expected list")
+ return response
+
+ def create_instruction(self, *, payload: dict[str, Any]) -> dict[str, Any]:
+ return self._request("POST", "/instructions", json_body=payload)
+
+ def update_instruction_active(self, *, instruction_id: str, active: bool) -> dict[str, Any]:
+ return self._request(
+ "PUT",
+ f"/instructions/{instruction_id}",
+ json_body={"active": active},
+ )
+
+ def list_entities_by_document(
+ self,
+ *,
+ partition: str,
+ document_id: str,
+ cursor: str | None = None,
+ page_size: int = 100,
+ ) -> dict[str, Any]:
+ return self._request(
+ "GET",
+ f"/documents/{document_id}/entities",
+ partition=partition,
+ query={"cursor": cursor, "page_size": page_size},
+ )
+
+
+def build_local_docs(
+ *,
+ refs: list[str],
+ partition: str,
+ docs_base_url: str,
+ repo_name: str,
+ source: str,
+ commit_sha: str,
+) -> list[LocalDoc]:
+ docs: list[LocalDoc] = []
+
+ visibility = "shared" if partition == "shared_docs" else "tenant"
+ tenant_id = partition.removeprefix("tenant_") if partition.startswith("tenant_") else partition
+
+ for ref in refs:
+ path = resolve_ref_path(ref)
+ if path is None:
+ log(f"[WARN] Missing file for docs ref '{ref}', skipping")
+ continue
+
+ rel_path = path.relative_to(REPO_ROOT)
+ if rel_path.parts[0] in {"snippets", "specs"}:
+ continue
+
+ raw_text = path.read_text(encoding="utf-8", errors="ignore")
+ fallback_title = ref.rsplit("/", 1)[-1].replace("-", " ").strip().title() or ref
+ content, fm = normalize_doc_text(raw_text, fallback_title)
+
+ content_hash = sha256_text(content)
+
+ url_path = "/" + ref.lstrip("/")
+ url_full = docs_base_url.rstrip("/") + url_path
+
+ taxonomy = derive_taxonomy(
+ ref=ref,
+ title=fm.get("title", fallback_title),
+ description=fm.get("description", ""),
+ frontmatter_tags=fm.get("tags", []),
+ )
+
+ metadata: dict[str, Any] = {
+ "source": source,
+ "repo": repo_name,
+ "docs_ref": ref,
+ "url_path": url_path,
+ "url_full": url_full,
+ "title": fm.get("title", fallback_title),
+ "description": fm.get("description", ""),
+ "content_hash": content_hash,
+ "visibility": visibility,
+ "tenant_id": tenant_id,
+ }
+ metadata.update(taxonomy)
+ if commit_sha:
+ metadata["commit_sha"] = commit_sha
+
+ external_id = f"repo:{repo_name}|partition:{partition}|ref:{ref}"
+ name = ref
+
+ docs.append(
+ LocalDoc(
+ ref=ref,
+ path=path,
+ name=name,
+ external_id=external_id,
+ content=content,
+ content_hash=content_hash,
+ metadata=metadata,
+ )
+ )
+
+ return docs
+
+
+def compare_metadata_patch(remote_metadata: dict[str, Any], desired_metadata: dict[str, Any]) -> dict[str, Any]:
+ patch: dict[str, Any] = {}
+
+ for key in MANAGED_METADATA_KEYS:
+ remote_present = key in remote_metadata
+ desired_present = key in desired_metadata
+
+ if desired_present and remote_metadata.get(key) != desired_metadata.get(key):
+ patch[key] = desired_metadata[key]
+ elif remote_present and not desired_present:
+ patch[key] = None
+
+ return patch
+
+
+def is_managed_remote_doc(doc: dict[str, Any], *, source: str, repo_name: str) -> bool:
+ metadata = doc.get("metadata") or {}
+ return metadata.get("source") == source and metadata.get("repo") == repo_name
+
+
+def pick_latest_doc(docs: list[dict[str, Any]]) -> tuple[dict[str, Any], list[dict[str, Any]]]:
+ def updated_at_key(doc: dict[str, Any]) -> str:
+ return str(doc.get("updated_at") or "")
+
+ ordered = sorted(docs, key=updated_at_key, reverse=True)
+ return ordered[0], ordered[1:]
+
+
+def poll_changed_documents(
+ *,
+ client: RagieClient,
+ partition: str,
+ document_ids: list[str],
+ timeout_seconds: int,
+ interval_seconds: float,
+ allow_indexed: bool,
+) -> None:
+ if not document_ids:
+ return
+
+ success_statuses = {"ready"}
+ if allow_indexed:
+ success_statuses.update({"indexed", "summary_indexed", "keyword_indexed"})
+
+ pending = set(document_ids)
+ failures: list[tuple[str, list[str]]] = []
+ deadline = time.time() + timeout_seconds
+
+ while pending and time.time() < deadline:
+ for document_id in list(pending):
+ doc = client.get_document(partition=partition, document_id=document_id)
+ status = str(doc.get("status") or "").strip().lower()
+ if status in success_statuses:
+ pending.remove(document_id)
+ continue
+ if status in TERMINAL_FAILURE_STATUSES:
+ pending.remove(document_id)
+ errors = doc.get("errors") or []
+ if not isinstance(errors, list):
+ errors = [str(errors)]
+ failures.append((document_id, [str(e) for e in errors]))
+
+ if pending:
+ time.sleep(interval_seconds)
+
+ if pending:
+ waiting = ", ".join(sorted(pending))
+ raise SyncError(
+ f"Timed out waiting for Ragie documents to finish indexing in partition '{partition}': {waiting}"
+ )
+
+ if failures:
+ details = "; ".join(
+ f"{doc_id}: {', '.join(errs) if errs else 'unknown error'}" for doc_id, errs in failures
+ )
+ raise SyncError(f"One or more Ragie documents failed indexing: {details}")
+
+
+def _json_equal(left: Any, right: Any) -> bool:
+ return json.dumps(left, sort_keys=True, separators=(",", ":"), ensure_ascii=True) == json.dumps(
+ right,
+ sort_keys=True,
+ separators=(",", ":"),
+ ensure_ascii=True,
+ )
+
+
+def ensure_partition_configuration(
+ *,
+ client: RagieClient,
+ partition: str,
+ description: str,
+ metadata_schema: dict[str, Any],
+ dry_run: bool,
+) -> None:
+ partitions = client.list_partitions()
+ exists = any(str(item.get("name") or "") == partition for item in partitions)
+
+ if not exists:
+ if dry_run:
+ log(f"[DRY-RUN] CREATE_PARTITION {partition}")
+ else:
+ client.create_partition(
+ name=partition,
+ description=description,
+ metadata_schema=metadata_schema,
+ )
+ log(f"[PARTITION_CREATE] {partition}")
+
+ if dry_run and not exists:
+ log(f"[DRY-RUN] PATCH_PARTITION {partition} keys=[context_aware,description,metadata_schema]")
+ return
+
+ detail = client.get_partition(partition_id=partition)
+ patch: dict[str, Any] = {}
+
+ if detail.get("context_aware") is not True:
+ patch["context_aware"] = True
+ if description and str(detail.get("description") or "") != description:
+ patch["description"] = description
+ if not _json_equal(detail.get("metadata_schema"), metadata_schema):
+ patch["metadata_schema"] = metadata_schema
+
+ if not patch:
+ log(f"[INFO] Partition '{partition}' already configured for context-aware retrieval")
+ return
+
+ if dry_run:
+ keys = ",".join(sorted(patch.keys()))
+ log(f"[DRY-RUN] PATCH_PARTITION {partition} keys=[{keys}]")
+ return
+
+ # Ragie currently rejects context_aware + description in the same PATCH payload.
+ # Apply in two steps when both are needed.
+ non_context_patch = {
+ key: patch[key]
+ for key in ("description", "metadata_schema")
+ if key in patch
+ }
+ if non_context_patch:
+ client.update_partition(
+ partition_id=partition,
+ description=non_context_patch.get("description"),
+ metadata_schema=non_context_patch.get("metadata_schema"),
+ )
+ keys = ",".join(sorted(non_context_patch.keys()))
+ log(f"[PARTITION_PATCH] {partition} keys=[{keys}]")
+
+ if "context_aware" in patch:
+ client.update_partition(
+ partition_id=partition,
+ context_aware=bool(patch["context_aware"]),
+ )
+ log(f"[PARTITION_PATCH] {partition} keys=[context_aware]")
+
+
+def ensure_entity_instruction(
+ *,
+ client: RagieClient,
+ partition: str,
+ source: str,
+ repo_name: str,
+ instruction_name: str,
+ scope: str,
+ dry_run: bool,
+) -> bool:
+ expected_payload: dict[str, Any] = {
+ "name": instruction_name,
+ "active": True,
+ "scope": scope,
+ "prompt": DEFAULT_ENTITY_INSTRUCTION_PROMPT,
+ "entity_schema": build_entity_schema(),
+ "filter": {
+ "source": {"$eq": source},
+ "repo": {"$eq": repo_name},
+ },
+ "partition": partition,
+ }
+
+ instructions = client.list_instructions()
+ matches = [inst for inst in instructions if str(inst.get("name") or "") == instruction_name]
+
+ if not matches:
+ if dry_run:
+ log(f"[DRY-RUN] CREATE_INSTRUCTION {instruction_name} partition={partition}")
+ return False
+ created = client.create_instruction(payload=expected_payload)
+ log(f"[INSTRUCTION_CREATE] {instruction_name} id={created.get('id')}")
+ return True
+
+ instruction = matches[0]
+ if len(matches) > 1:
+ log(f"[WARN] Multiple instructions found for name '{instruction_name}', using newest by API order")
+
+ instruction_id = str(instruction.get("id") or "")
+ if not bool(instruction.get("active")):
+ if dry_run:
+ log(f"[DRY-RUN] ACTIVATE_INSTRUCTION {instruction_name} id={instruction_id}")
+ elif instruction_id:
+ client.update_instruction_active(instruction_id=instruction_id, active=True)
+ log(f"[INSTRUCTION_ACTIVATE] {instruction_name} id={instruction_id}")
+
+ drift_fields: list[str] = []
+ if str(instruction.get("partition") or "") != partition:
+ drift_fields.append("partition")
+ if str(instruction.get("scope") or "") != scope:
+ drift_fields.append("scope")
+ if str(instruction.get("prompt") or "") != DEFAULT_ENTITY_INSTRUCTION_PROMPT:
+ drift_fields.append("prompt")
+ if not _json_equal(instruction.get("entity_schema"), expected_payload["entity_schema"]):
+ drift_fields.append("entity_schema")
+ if not _json_equal(instruction.get("filter"), expected_payload["filter"]):
+ drift_fields.append("filter")
+
+ if drift_fields:
+ joined = ",".join(sorted(drift_fields))
+ log(
+ "[WARN] Instruction config drift detected for "
+ f"'{instruction_name}' (fields: {joined}). Ragie only supports active-state updates; "
+ "delete/recreate instruction to apply config changes."
+ )
+ else:
+ log(f"[INFO] Instruction '{instruction_name}' already configured")
+
+ return False
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description="Sync SourceMedium docs into Ragie")
+ parser.add_argument("--partition", required=True, help="Ragie partition (e.g. shared_docs, tenant_acme)")
+ parser.add_argument(
+ "--mode",
+ choices=["incremental", "full"],
+ default="incremental",
+ help="Sync mode (currently both modes use full diff-based reconciliation)",
+ )
+ parser.add_argument(
+ "--doc-ref",
+ action="append",
+ default=[],
+ help="Optional docs ref to sync. Repeatable for multiple refs.",
+ )
+ parser.add_argument("--source", default="sourcemedium-docs", help="Managed metadata source marker")
+ parser.add_argument("--repo-name", default="sourcemedium-docs", help="Repo name for metadata/external_id")
+ parser.add_argument("--docs-base-url", default="https://docs.sourcemedium.com", help="Base URL for url_full metadata")
+ parser.add_argument("--base-url", default="https://api.ragie.ai", help="Ragie API base URL")
+ parser.add_argument("--commit-sha", default="", help="Commit SHA to stamp in metadata")
+ parser.add_argument(
+ "--ensure-partition-context-aware",
+ action="store_true",
+ help="Ensure partition has context-aware retrieval enabled with description + metadata schema",
+ )
+ parser.add_argument(
+ "--partition-description",
+ default="",
+ help="Optional partition description override used with --ensure-partition-context-aware",
+ )
+ parser.add_argument(
+ "--ensure-entity-instruction",
+ action="store_true",
+ help="Ensure a partition-scoped entity extraction instruction exists",
+ )
+ parser.add_argument(
+ "--entity-instruction-name",
+ default="",
+ help="Optional instruction name override (default: sourcemedium-doc-entities-v1-)",
+ )
+ parser.add_argument(
+ "--entity-instruction-scope",
+ choices=["document", "chunk"],
+ default="document",
+ help="Instruction scope for entity extraction",
+ )
+ parser.add_argument("--dry-run", action="store_true", help="Compute and print actions without writing to Ragie")
+ parser.add_argument("--allow-indexed", action="store_true", help="Treat indexed/summary_indexed/keyword_indexed as success")
+ parser.add_argument("--timeout", type=int, default=30, help="HTTP timeout seconds")
+ parser.add_argument("--max-retries", type=int, default=4, help="HTTP retry attempts for retryable errors")
+ parser.add_argument("--retry-base-delay", type=float, default=0.5, help="Exponential backoff base delay in seconds")
+ parser.add_argument("--poll-timeout", type=int, default=600, help="Polling timeout in seconds")
+ parser.add_argument("--poll-interval", type=float, default=2.0, help="Polling interval in seconds")
+ parser.add_argument(
+ "--skip-remote",
+ action="store_true",
+ help="Skip Ragie API reads/writes (useful for local content-shaping validation)",
+ )
+ return parser.parse_args()
+
+
+def main() -> int:
+ args = parse_args()
+
+ load_local_env(ENV_FILE)
+
+ partition = sanitize_partition(args.partition)
+
+ commit_sha = args.commit_sha.strip() or os.environ.get("GITHUB_SHA", "").strip()
+
+ refs = load_docs_refs()
+ refs = scope_refs_for_partition(refs=refs, partition=partition)
+ requested_doc_refs = [r.lstrip("/") for r in args.doc_ref if str(r).strip()]
+ partial_sync = bool(requested_doc_refs)
+ if requested_doc_refs:
+ wanted = set(requested_doc_refs)
+ refs = [r for r in refs if r in wanted]
+ missing = sorted(wanted - set(refs))
+ if missing:
+ raise SyncError(
+ f"doc_ref(s) not available for partition '{partition}': {', '.join(missing)}"
+ )
+
+ local_docs = build_local_docs(
+ refs=refs,
+ partition=partition,
+ docs_base_url=args.docs_base_url,
+ repo_name=args.repo_name,
+ source=args.source,
+ commit_sha=commit_sha,
+ )
+
+ if not local_docs:
+ raise SyncError("No local docs discovered to sync")
+
+ local_by_external = {doc.external_id: doc for doc in local_docs}
+ local_refs = {doc.ref for doc in local_docs}
+
+ log(f"[INFO] Local docs discovered: {len(local_docs)}")
+
+ if args.skip_remote:
+ log("[INFO] --skip-remote enabled, ending after local discovery")
+ return 0
+
+ api_key = os.environ.get("RAGIE_API_KEY", "").strip()
+ if not api_key:
+ raise SyncError("RAGIE_API_KEY is not set (env or .env)")
+
+ client = RagieClient(
+ api_key=api_key,
+ base_url=args.base_url,
+ timeout=args.timeout,
+ max_retries=args.max_retries,
+ retry_base_delay=args.retry_base_delay,
+ )
+
+ created_instruction = False
+ if args.ensure_partition_context_aware:
+ desired_description = args.partition_description.strip() or default_partition_description(partition)
+ ensure_partition_configuration(
+ client=client,
+ partition=partition,
+ description=desired_description,
+ metadata_schema=build_partition_metadata_schema(),
+ dry_run=args.dry_run,
+ )
+
+ if args.ensure_entity_instruction:
+ instruction_name = args.entity_instruction_name.strip() or default_entity_instruction_name(partition)
+ created_instruction = ensure_entity_instruction(
+ client=client,
+ partition=partition,
+ source=args.source,
+ repo_name=args.repo_name,
+ instruction_name=instruction_name,
+ scope=args.entity_instruction_scope,
+ dry_run=args.dry_run,
+ )
+
+ remote_docs_all = client.list_documents(partition=partition)
+ managed_remote_docs = [
+ doc for doc in remote_docs_all if is_managed_remote_doc(doc, source=args.source, repo_name=args.repo_name)
+ ]
+
+ log(
+ f"[INFO] Remote docs in partition '{partition}': total={len(remote_docs_all)} managed={len(managed_remote_docs)}"
+ )
+
+ grouped_by_external: dict[str, list[dict[str, Any]]] = {}
+ remote_without_external: list[dict[str, Any]] = []
+ for doc in managed_remote_docs:
+ ext = str(doc.get("external_id") or "").strip()
+ if not ext:
+ remote_without_external.append(doc)
+ continue
+ grouped_by_external.setdefault(ext, []).append(doc)
+
+ remote_by_external: dict[str, dict[str, Any]] = {}
+ duplicate_docs: list[dict[str, Any]] = []
+
+ for external_id, docs in grouped_by_external.items():
+ keep, dups = pick_latest_doc(docs)
+ remote_by_external[external_id] = keep
+ duplicate_docs.extend(dups)
+
+ create_docs: list[LocalDoc] = []
+ update_raw_docs: list[tuple[LocalDoc, dict[str, Any]]] = []
+ patch_metadata_docs: list[tuple[LocalDoc, dict[str, Any], dict[str, Any]]] = []
+
+ for external_id, local in local_by_external.items():
+ remote = remote_by_external.get(external_id)
+ if remote is None:
+ create_docs.append(local)
+ continue
+
+ remote_metadata = remote.get("metadata") or {}
+ if not isinstance(remote_metadata, dict):
+ remote_metadata = {}
+
+ metadata_patch = compare_metadata_patch(remote_metadata, local.metadata)
+ remote_hash = str(remote_metadata.get("content_hash") or "")
+ needs_raw_update = remote_hash != local.content_hash
+
+ if needs_raw_update:
+ update_raw_docs.append((local, remote))
+
+ if metadata_patch:
+ patch_metadata_docs.append((local, remote, metadata_patch))
+
+ stale_docs: list[dict[str, Any]] = []
+ stale_no_external_docs: list[dict[str, Any]] = []
+ skipped_no_external = 0
+
+ if not partial_sync:
+ stale_external_ids = sorted(set(remote_by_external.keys()) - set(local_by_external.keys()))
+ stale_docs = [remote_by_external[eid] for eid in stale_external_ids]
+
+ for doc in remote_without_external:
+ metadata = doc.get("metadata") or {}
+ docs_ref = str(metadata.get("docs_ref") or "").strip()
+ if docs_ref and docs_ref not in local_refs:
+ stale_no_external_docs.append(doc)
+ else:
+ skipped_no_external += 1
+ else:
+ # In partial mode, only clean duplicates for targeted external_ids.
+ duplicate_docs = [
+ doc for doc in duplicate_docs if str(doc.get("external_id") or "") in set(local_by_external.keys())
+ ]
+
+ log(
+ "[INFO] Plan: "
+ f"create={len(create_docs)} "
+ f"update_raw={len(update_raw_docs)} "
+ f"patch_metadata={len(patch_metadata_docs)} "
+ f"delete_stale={len(stale_docs)} "
+ f"delete_duplicates={len(duplicate_docs)} "
+ f"delete_stale_no_external={len(stale_no_external_docs)}"
+ )
+ if partial_sync:
+ log("[INFO] Partial sync mode enabled via --doc-ref (stale deletion disabled)")
+ if skipped_no_external:
+ log(f"[WARN] Managed docs without external_id kept (no safe delete signal): {skipped_no_external}")
+
+ if args.dry_run:
+ for doc in create_docs[:20]:
+ log(f"[DRY-RUN] CREATE {doc.ref}")
+ for local, remote in update_raw_docs[:20]:
+ log(f"[DRY-RUN] UPDATE_RAW {local.ref} doc_id={remote.get('id')}")
+ for local, remote, metadata_patch in patch_metadata_docs[:20]:
+ patch_keys = ",".join(sorted(metadata_patch.keys()))
+ log(f"[DRY-RUN] PATCH_METADATA {local.ref} doc_id={remote.get('id')} keys=[{patch_keys}]")
+ for doc in stale_docs[:20]:
+ log(f"[DRY-RUN] DELETE_STALE external_id={doc.get('external_id')} doc_id={doc.get('id')}")
+ for doc in duplicate_docs[:20]:
+ log(f"[DRY-RUN] DELETE_DUPLICATE external_id={doc.get('external_id')} doc_id={doc.get('id')}")
+ for doc in stale_no_external_docs[:20]:
+ md = doc.get("metadata") or {}
+ log(f"[DRY-RUN] DELETE_STALE_NO_EXTERNAL docs_ref={md.get('docs_ref')} doc_id={doc.get('id')}")
+ log("[INFO] Dry-run complete")
+ return 0
+
+ changed_document_ids: list[str] = []
+
+ for local in create_docs:
+ response = client.create_document_raw(
+ partition=partition,
+ name=local.name,
+ external_id=local.external_id,
+ metadata=local.metadata,
+ data=local.content,
+ )
+ doc_id = str(response.get("id") or "")
+ if not doc_id:
+ raise SyncError(f"Create returned no document id for {local.ref}")
+ changed_document_ids.append(doc_id)
+ log(f"[CREATE] {local.ref} -> {doc_id}")
+
+ for local, remote in update_raw_docs:
+ doc_id = str(remote.get("id") or "")
+ if not doc_id:
+ raise SyncError(f"Remote document missing id for update: {local.ref}")
+ client.update_document_raw(partition=partition, document_id=doc_id, data=local.content)
+ changed_document_ids.append(doc_id)
+ log(f"[UPDATE_RAW] {local.ref} -> {doc_id}")
+
+ for local, remote, metadata_patch in patch_metadata_docs:
+ doc_id = str(remote.get("id") or "")
+ if not doc_id:
+ raise SyncError(f"Remote document missing id for metadata patch: {local.ref}")
+ client.patch_document_metadata(
+ partition=partition,
+ document_id=doc_id,
+ metadata_patch=metadata_patch,
+ )
+ log(f"[PATCH_METADATA] {local.ref} -> {doc_id}")
+
+ for doc in stale_docs:
+ doc_id = str(doc.get("id") or "")
+ if not doc_id:
+ continue
+ client.delete_document(partition=partition, document_id=doc_id, async_delete=True)
+ log(f"[DELETE_STALE] doc_id={doc_id}")
+
+ for doc in duplicate_docs:
+ doc_id = str(doc.get("id") or "")
+ if not doc_id:
+ continue
+ client.delete_document(partition=partition, document_id=doc_id, async_delete=True)
+ log(f"[DELETE_DUPLICATE] doc_id={doc_id}")
+
+ for doc in stale_no_external_docs:
+ doc_id = str(doc.get("id") or "")
+ if not doc_id:
+ continue
+ client.delete_document(partition=partition, document_id=doc_id, async_delete=True)
+ log(f"[DELETE_STALE_NO_EXTERNAL] doc_id={doc_id}")
+
+ changed_document_ids = sorted(set(changed_document_ids))
+
+ poll_changed_documents(
+ client=client,
+ partition=partition,
+ document_ids=changed_document_ids,
+ timeout_seconds=args.poll_timeout,
+ interval_seconds=args.poll_interval,
+ allow_indexed=args.allow_indexed,
+ )
+
+ log(
+ f"[OK] Sync complete for partition '{partition}': "
+ f"created={len(create_docs)} updated={len(update_raw_docs)} "
+ f"patched={len(patch_metadata_docs)} deleted={len(stale_docs) + len(duplicate_docs) + len(stale_no_external_docs)}"
+ )
+ if created_instruction and not changed_document_ids:
+ log(
+ "[WARN] Entity instruction was created but no documents changed in this run. "
+ "Run a full sync to backfill extracted entities on existing docs."
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ try:
+ raise SystemExit(main())
+ except SyncError as err:
+ log(f"[ERROR] {err}")
+ raise SystemExit(1)
diff --git a/scripts/sync-docsjson-smtables.js b/scripts/sync-docsjson-smtables.js
new file mode 100644
index 0000000..0824d3a
--- /dev/null
+++ b/scripts/sync-docsjson-smtables.js
@@ -0,0 +1,70 @@
+const fs = require('fs');
+const path = require('path');
+
+const DOCS_JSON = path.join(__dirname, '..', 'docs.json');
+const SCHEMA_JSON = path.join(__dirname, '..', 'yaml-files', 'latest-v2-schemas-10-20-25.json');
+
+function loadJSON(p) { return JSON.parse(fs.readFileSync(p, 'utf8')); }
+
+function collectTables(schema) {
+ const out = new Map(); // name -> type
+ for (const r of schema) {
+ if (!r || r.dataset_name !== 'sm_transformed_v2') continue;
+ if (!out.has(r.table_name)) out.set(r.table_name, r.table_type || '');
+ }
+ // Desired order: Dimension, Fact, One Big Table, Report, then name ASC
+ const order = { 'Dimension': 1, 'Fact': 2, 'One Big Table': 3, 'Report': 4 };
+ return Array.from(out.entries())
+ .sort((a, b) => {
+ const [na, ta] = a; const [nb, tb] = b;
+ const oa = order[ta] || 99; const ob = order[tb] || 99;
+ if (oa !== ob) return oa - ob;
+ return na.localeCompare(nb);
+ })
+ .map(([name]) => `data-activation/data-tables/sm_transformed_v2/${name}`);
+}
+
+function updateSourceMediumTablesNav(docs, pages) {
+ // docs.navigation.tabs[].groups[...] possibly nested groups
+ const tabs = docs?.navigation?.tabs;
+ if (!Array.isArray(tabs)) return false;
+
+ let updated = false;
+ function walkGroups(node) {
+ if (!node) return;
+ if (node.group === 'SourceMedium Tables' && Array.isArray(node.pages)) {
+ node.pages = pages;
+ updated = true;
+ return; // still continue, in case of duplicates
+ }
+ if (Array.isArray(node.pages)) {
+ for (const p of node.pages) {
+ if (p && typeof p === 'object') walkGroups(p);
+ }
+ }
+ if (Array.isArray(node.groups)) {
+ for (const g of node.groups) walkGroups(g);
+ }
+ }
+
+ for (const tab of tabs) {
+ walkGroups(tab);
+ }
+ return updated;
+}
+
+function main() {
+ const docs = loadJSON(DOCS_JSON);
+ const schema = loadJSON(SCHEMA_JSON);
+ const pages = collectTables(schema);
+ const ok = updateSourceMediumTablesNav(docs, pages);
+ if (!ok) {
+ console.error('SourceMedium Tables group not found or navigation shape unexpected. No changes made.');
+ process.exit(0);
+ }
+ fs.writeFileSync(DOCS_JSON, JSON.stringify(docs, null, 2) + '\n', 'utf8');
+ console.log('Updated docs.json SourceMedium Tables with', pages.length, 'entries.');
+}
+
+if (require.main === module) main();
+
diff --git a/scripts/update-sm-v2-from-json.js b/scripts/update-sm-v2-from-json.js
new file mode 100644
index 0000000..bec51de
--- /dev/null
+++ b/scripts/update-sm-v2-from-json.js
@@ -0,0 +1,223 @@
+const fs = require('fs');
+const path = require('path');
+
+const JSON_PATH = path.join(__dirname, '..', 'yaml-files', 'latest-v2-schemas-10-20-25.json');
+const TABLES_DIR = path.join(__dirname, '..', 'data-activation', 'data-tables', 'sm_transformed_v2');
+
+function loadLatest() {
+ const raw = fs.readFileSync(JSON_PATH, 'utf8');
+ const rows = JSON.parse(raw);
+ const byTable = new Map();
+ for (const r of rows) {
+ if (!r || r.dataset_name !== 'sm_transformed_v2') continue;
+ const t = r.table_name;
+ if (!byTable.has(t)) byTable.set(t, { table: t, table_type: r.table_type || '', description: r.table_description || '', columns: new Map() });
+ const entry = byTable.get(t);
+ // Update table description with the most recent non-empty value
+ if (r.table_description && r.table_description.trim()) {
+ entry.description = r.table_description.trim();
+ }
+ const col = r.column_name;
+ if (!col) continue;
+ const cdesc = (r.column_description || '').trim();
+ if (!entry.columns.has(col)) {
+ entry.columns.set(col, cdesc);
+ } else if (cdesc) {
+ entry.columns.set(col, cdesc);
+ }
+ }
+ return byTable;
+}
+
+function yamlEscapeFolded(text) {
+ // Keep text as-is; folded style handles most characters fine.
+ return text.replace(/\r\n/g, '\n');
+}
+
+function generateYaml(table, description, columns) {
+ const lines = [];
+ lines.push('```yaml');
+ lines.push('version: 2');
+ lines.push('');
+ lines.push('models:');
+ lines.push(` - name: ${table}`);
+ lines.push(' description: >');
+ const descLines = yamlEscapeFolded(description || '').split('\n');
+ if (descLines.length === 0 || (descLines.length === 1 && descLines[0] === '')) {
+ lines.push(' ');
+ } else {
+ for (const dl of descLines) {
+ lines.push(` ${dl}`);
+ }
+ }
+ lines.push(' columns:');
+ const sorted = Array.from(columns.keys()).sort((a, b) => a.localeCompare(b));
+ for (const col of sorted) {
+ lines.push(` - name: ${col}`);
+ lines.push(' description: >');
+ const cdesc = yamlEscapeFolded(columns.get(col) || '');
+ const cdescLines = cdesc.split('\n');
+ if (cdescLines.length === 0 || (cdescLines.length === 1 && cdescLines[0] === '')) {
+ lines.push(' ');
+ } else {
+ for (const cl of cdescLines) {
+ lines.push(` ${cl}`);
+ }
+ }
+ lines.push('');
+ }
+ lines.push('```');
+ return lines.join('\n');
+}
+
+function updateMdx(filePath, yamlBlock) {
+ const original = fs.readFileSync(filePath, 'utf8');
+ const start = original.indexOf('```yaml');
+ if (start === -1) return false;
+ const end = original.indexOf('```', start + 7);
+ if (end === -1) return false;
+ const before = original.slice(0, start);
+ const after = original.slice(end + 3);
+ const updated = before + yamlBlock + after;
+ fs.writeFileSync(filePath, updated, 'utf8');
+ return true;
+}
+
+function ensureMdx(filePath, table, description, columns) {
+ if (fs.existsSync(filePath)) return false;
+ const frontmatter = `---\n` +
+ `title: '${table}'\n` +
+ `description: ''\n` +
+ `---\n\n`;
+ const yamlBlock = generateYaml(table, description, columns);
+ fs.writeFileSync(filePath, frontmatter + yamlBlock + '\n', 'utf8');
+ return true;
+}
+
+function shortBlurb(text) {
+ if (!text) return '';
+ const s = String(text).trim();
+ const periodIdx = s.indexOf('.');
+ let first = periodIdx > -1 ? s.slice(0, periodIdx + 1) : s;
+ if (first.length > 140) first = first.slice(0, 137).trimEnd() + '...';
+ return first;
+}
+
+function generateIndex(byTable) {
+ const groups = {
+ 'Dimension': [],
+ 'Fact': [],
+ 'One Big Table': [],
+ 'Report': []
+ };
+ for (const [, v] of byTable) {
+ const type = v.table_type || '';
+ if (groups[type]) groups[type].push(v);
+ }
+ for (const k of Object.keys(groups)) groups[k].sort((a, b) => a.table.localeCompare(b.table));
+
+ const lines = [];
+ lines.push('---');
+ lines.push('title: "SM Transformed v2 Tables"');
+ lines.push('description: "Browse all tables in the sm_transformed_v2 schema, grouped by type."');
+ lines.push('---');
+ lines.push('');
+ lines.push('Welcome to the sm_transformed_v2 schema. Use this page to quickly jump to table-level documentation. Tables are grouped by their role in the model for clarity.');
+ lines.push('');
+
+ if (groups['Dimension'].length) {
+ lines.push('### Dimensions');
+ lines.push('');
+ for (const v of groups['Dimension']) {
+ const t = v.table;
+ lines.push(` `);
+ lines.push(' ' + shortBlurb(v.description));
+ lines.push(' ');
+ }
+ lines.push('');
+ lines.push('');
+ }
+
+ if (groups['Fact'].length) {
+ lines.push('### Facts');
+ lines.push('');
+ for (const v of groups['Fact']) {
+ const t = v.table;
+ lines.push(` `);
+ lines.push(' ' + shortBlurb(v.description));
+ lines.push(' ');
+ }
+ lines.push('');
+ lines.push('');
+ }
+
+ if (groups['One Big Table'].length) {
+ lines.push('### OBT (One Big Table)');
+ lines.push('');
+ for (const v of groups['One Big Table']) {
+ const t = v.table;
+ lines.push(` `);
+ lines.push(' ' + shortBlurb(v.description));
+ lines.push(' ');
+ }
+ lines.push('');
+ lines.push('');
+ }
+
+ if (groups['Report'].length) {
+ lines.push('### Reports');
+ lines.push('');
+ for (const v of groups['Report']) {
+ const t = v.table;
+ lines.push(` `);
+ lines.push(' ' + shortBlurb(v.description));
+ lines.push(' ');
+ }
+ lines.push('');
+ lines.push('');
+ }
+
+ lines.push(' ');
+ lines.push('');
+ lines.push('Need something else in this index? Ping us and we’ll add it.');
+ lines.push('');
+ return lines.join('\n');
+}
+
+function main() {
+ const byTable = loadLatest();
+ const mdxFiles = fs.readdirSync(TABLES_DIR).filter(f => f.endsWith('.mdx'));
+ const results = [];
+ // Update existing MDX files that match JSON tables (skip index.mdx)
+ for (const f of mdxFiles) {
+ if (f === 'index.mdx') continue;
+ const filePath = path.join(TABLES_DIR, f);
+ const table = path.basename(f, '.mdx');
+ const entry = byTable.get(table);
+ if (!entry) {
+ results.push({ file: f, status: 'skipped', reason: 'table not found in JSON' });
+ continue;
+ }
+ const yamlBlock = generateYaml(entry.table, entry.description, entry.columns);
+ const ok = updateMdx(filePath, yamlBlock);
+ results.push({ file: f, status: ok ? 'updated' : 'failed', reason: ok ? '' : 'yaml block not found' });
+ }
+ // Create missing MDX files for tables present in JSON but not on disk
+ for (const [table, entry] of byTable) {
+ const fileName = `${table}.mdx`;
+ const filePath = path.join(TABLES_DIR, fileName);
+ if (!fs.existsSync(filePath)) {
+ const created = ensureMdx(filePath, table, entry.description, entry.columns);
+ results.push({ file: fileName, status: created ? 'created' : 'error', reason: created ? '' : 'create failed' });
+ }
+ }
+ // Regenerate index from JSON
+ const indexMdx = generateIndex(byTable);
+ fs.writeFileSync(path.join(TABLES_DIR, 'index.mdx'), indexMdx, 'utf8');
+
+ console.log(JSON.stringify(results, null, 2));
+}
+
+if (require.main === module) {
+ main();
+}
diff --git a/skill.md b/skill.md
new file mode 100644
index 0000000..9fef7e8
--- /dev/null
+++ b/skill.md
@@ -0,0 +1,43 @@
+---
+name: sourcemedium
+description: SourceMedium AI Analyst capabilities for BigQuery analysis. Install the full skill package for your coding agent.
+---
+
+# SourceMedium AI Analyst
+
+Install the full skill package for your coding agent:
+
+```bash
+npx skills add source-medium/skills --skill sm-bigquery-analyst
+```
+
+## Quick Start (Copy/Paste)
+
+Copy this prompt and give it to your coding agent:
+
+```
+Install the SourceMedium BigQuery analyst skill and help me verify my setup:
+
+1. Run: npx skills add source-medium/skills --skill sm-bigquery-analyst
+2. Run the setup verification commands from the skill
+3. Confirm my BigQuery access is working
+
+My BigQuery project ID is: [YOUR_PROJECT_ID]
+```
+
+## What you get
+
+| Skill | Description |
+|-------|-------------|
+| `sm-bigquery-analyst` | Query SourceMedium BigQuery safely. Emits SQL receipts. SELECT-only, cost-guarded. |
+
+## Features
+
+- **Setup verification** — validates gcloud/bq CLI, authentication, and table access
+- **Safe queries** — SELECT-only, dry-run first, cost-guarded
+- **SQL receipts** — every answer includes copy/paste SQL + verification command
+- **No fabrication** — if access fails, returns exact error and access request template
+
+## Documentation
+
+See [docs.sourcemedium.com/ai-analyst/agent-skills](https://docs.sourcemedium.com/ai-analyst/agent-skills) for full documentation.
diff --git a/skills b/skills
new file mode 160000
index 0000000..6923b7e
--- /dev/null
+++ b/skills
@@ -0,0 +1 @@
+Subproject commit 6923b7e06cf69bb1b794e6ed76a4e18eb8f9e70e
diff --git a/snippets/cpa-definition.mdx b/snippets/cpa-definition.mdx
index 9c3ce1d..044d121 100644
--- a/snippets/cpa-definition.mdx
+++ b/snippets/cpa-definition.mdx
@@ -1 +1,6 @@
+---
+title: "Snippet: CPA definition"
+description: "Reusable snippet defining cost per acquisition (CPA)"
+---
+
| Cost Per Acquisition | CPA = Spend / New Customers | |
diff --git a/snippets/executive-summary-module-and-table-metrics.mdx b/snippets/executive-summary-module-and-table-metrics.mdx
index 94080c7..4dd82c0 100644
--- a/snippets/executive-summary-module-and-table-metrics.mdx
+++ b/snippets/executive-summary-module-and-table-metrics.mdx
@@ -1,3 +1,8 @@
+---
+title: "Snippet: Executive Summary metrics"
+description: "Reusable snippet content for Executive Summary module metrics"
+---
+
some information
-
\ No newline at end of file
+
diff --git a/snippets/roas-definition.mdx b/snippets/roas-definition.mdx
index b75dfad..f1038d9 100644
--- a/snippets/roas-definition.mdx
+++ b/snippets/roas-definition.mdx
@@ -1 +1,6 @@
-ROAS (Return on Ad Spend) = Revenue / Ad Spend
\ No newline at end of file
+---
+title: "Snippet: ROAS definition"
+description: "Reusable snippet defining return on ad spend (ROAS)"
+---
+
+ROAS (Return on Ad Spend) = Revenue / Ad Spend
diff --git a/snippets/snippet-example.mdx b/snippets/snippet-example.mdx
index 089334c..0d021c6 100644
--- a/snippets/snippet-example.mdx
+++ b/snippets/snippet-example.mdx
@@ -1,3 +1,8 @@
+---
+title: "Snippet example"
+description: "Example reusable snippet for Mintlify components"
+---
+
## My Snippet
This is an example of a reusable snippet
diff --git a/snippets/test.mdx b/snippets/test.mdx
index 9c3ce1d..f3e0f51 100644
--- a/snippets/test.mdx
+++ b/snippets/test.mdx
@@ -1 +1,6 @@
+---
+title: "Snippet test"
+description: "Test snippet page (internal)"
+---
+
| Cost Per Acquisition | CPA = Spend / New Customers | |
diff --git a/snippets/tooltip-CPA.mdx b/snippets/tooltip-CPA.mdx
index a85a1f6..46d593b 100644
--- a/snippets/tooltip-CPA.mdx
+++ b/snippets/tooltip-CPA.mdx
@@ -1 +1,6 @@
-CPA
\ No newline at end of file
+---
+title: "Snippet: CPA tooltip"
+description: "Reusable tooltip snippet for cost per acquisition (CPA)"
+---
+
+CPA
diff --git a/snippets/ttpmta.mdx b/snippets/ttpmta.mdx
index 8e0f048..5eb598b 100644
--- a/snippets/ttpmta.mdx
+++ b/snippets/ttpmta.mdx
@@ -1 +1,6 @@
-MTA
\ No newline at end of file
+---
+title: "Snippet: MTA tooltip"
+description: "Reusable tooltip snippet defining multi-touch attribution (MTA)"
+---
+
+MTA
diff --git a/specs/query-library-spec-codex.md b/specs/query-library-spec-codex.md
new file mode 100644
index 0000000..28ad19c
--- /dev/null
+++ b/specs/query-library-spec-codex.md
@@ -0,0 +1,558 @@
+# Query Library (AI Analyst) — Spec (Codex)
+
+Status: In progress (Batches 1–12 shipped)
+Owner: Docs (Data Activation) + AI Analyst
+Last updated: 2026-01-29
+
+## Background
+
+We want a **high-quality, highly relevant query library** that:
+
+1) Improves the AI Analyst’s SQL generation (better patterns + fewer mistakes).
+2) Improves customer self-serve docs (“how to query SourceMedium tables”).
+3) Creates a testable, versioned set of “gold” SQL templates we can QA/validate in batches.
+
+We already have three strong sources of truth:
+
+- **Uni2 SQL rules** (authoritative): `src/agent_core/agents/prompts.py` + `src/agent_core/domain_tables.py`.
+- **QA patterns + SQL guidelines** (useful but secondary when conflicting): `uni-training/.claude/shared/*`.
+- **Eval dataset + artifacts** (seed set): `uni-training/eval3.json` (120 Qs) plus pre-generated SQL artifacts under `uni-training/questions_grouped/unique/Q*/artifacts/generated-queries.sql` (and sometimes `generated-queries_revised.sql`).
+
+Important conflict resolution rule:
+- If `uni-training/.claude` guidance conflicts with **uni2** logic, **prefer uni2**.
+
+Note on datasets:
+- `uni-training/eval3.json` is the primary seed for v0 because it maps cleanly to the `questions_grouped/unique/Q*/` artifact folders.
+- `uni-training/evaluation/training_simplified.json` is a useful supplemental pool, but not the v0 extraction source.
+
+## Goals
+
+- Establish a **repeatable batching workflow** (5–10 queries per batch) to: prioritize → normalize → QA → validate → publish.
+- Build an initial “gold” set focused on **core tables** and **high-frequency questions** (revenue/orders/AOV, products, new vs repeat, basic marketing/ad performance, cohorts).
+- Ensure every published query is:
+ - safe to copy/paste (uses placeholders like `your_project.sm_transformed_v2.
`),
+ - schema-correct (columns exist),
+ - aligned with uni2 business logic conventions (filters, attribution semantics, channel semantics).
+
+## Non-goals (for v0)
+
+- Exhaustive coverage of every table and edge-case.
+- Complex multi-touch/MTA journey analysis (only include when explicit intent; later batches).
+- Highly tenant-specific enumerations (UTM/campaign value lists) embedded directly in docs.
+
+## Guiding Principles (Hard Requirements)
+
+### SQL correctness + safety
+
+- **No invented columns**: only reference documented columns for the table.
+- **Always use valid-order filters** on order tables:
+ - `WHERE is_order_sm_valid = TRUE` (and only use `order_cancelled_at` when it exists on the selected table).
+- **No LIKE/REGEXP on low-cardinality categorical columns** (uni2 rule):
+ - For dimensions like `sm_channel`, `source_system`, `sm_utm_source`, `sm_utm_medium`, `sm_utm_source_medium`, etc. use `=` / `IN` with normalized comparisons (e.g., `LOWER(TRIM(col)) = 'meta'`).
+ - If the query needs “contains”-style matching, prefer a **discovery-first** step that enumerates actual values, then exact-match in the final query.
+- **Assumptions header** at top of every “gold” query:
+ - `-- Assumptions: timeframe=<...> | metric=<...> | grain=<...> | scope=<...>`
+- **Channel semantics must be correct** (uni2 rule):
+ - `source_system` = system/platform of origin (ads platform vs commerce platform depends on table domain).
+ - `sm_channel` = normalized sales channel (`online_dtc`, `amazon`, `tiktok_shop`, etc.). Do not substitute one for the other.
+- **Default timeframe**:
+ - If query is an operational metric and the question lacks a timeframe, default to **last 30 days**.
+
+### Docs compatibility
+
+- SQL in docs should use:
+ - `your_project.sm_transformed_v2.
` (and `your_project.sm_experimental.
` only for explicitly experimental/MTA examples).
+- Keep examples compact and scannable:
+ - Prefer “one query per example” (or a clearly labeled 2-step pattern when discovery is required).
+
+## Where the Query Library Lives (Docs)
+
+We publish in two places (single source of truth + pointer):
+
+1) **SQL Query Library (canonical, BigQuery-facing)**
+ - Location: `sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`
+ - This is the canonical home for copy/paste SQL templates.
+
+2) **AI Analyst Query Library pointer (AI Analyst-facing)**
+ - Location: `sourcemedium-docs/ai-analyst/query-library/index.mdx`
+ - Purpose: link AI Analyst users to the canonical SQL Query Library page.
+
+3) **Per-table “Example Queries” sections** (table-oriented, schema-first; follow-up)
+ - Add a small curated set (2–5) to high-traffic tables under:
+ - `sourcemedium-docs/data-activation/data-tables/sm_transformed_v2/*.mdx`
+ - Start with:
+ - `obt_orders`, `dim_orders`, `obt_order_lines`, `rpt_executive_summary_daily`, `rpt_ad_performance_daily`, `rpt_cohort_ltv_*`, `rpt_outbound_message_performance_daily`, `obt_funnel_event_history`.
+
+Navigation note (v0):
+- We added a redirect from the old permalink `/data-activation/template-resources/sm-sql-recipe-directory` → `/data-activation/template-resources/sql-query-library` in `sourcemedium-docs/docs.json`.
+
+## Current Progress
+
+### Batch 1 (shipped to docs)
+- Canonical page: `sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`
+- AI Analyst pointer: `sourcemedium-docs/ai-analyst/query-library/index.mdx`
+- Batch 1 queries included: Q011, Q001, Q022, Q021, Q003, Q119, Q060, Q023
+- Validation status:
+ - Static schema/column validation: done (docs validator).
+ - Live BigQuery dry-run validation (`bq query --dry_run ...`): pending engineering gate.
+
+### Batch 2 (shipped to docs; pending dry-run gate)
+- Canonical page: `sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`
+- Batch 2 queries added: Q081, Q082, Q083, Q017, Q062, Q115
+- Why these queries (selection rationale):
+ - **High-frequency questions** we repeatedly see (ROAS trend, acquisition trend, top products, refunds, channel mix, new-customer product mix).
+ - **Core, stable tables** only (`sm_transformed_v2`): `rpt_ad_performance_daily`, `rpt_executive_summary_daily`, `obt_orders`, `obt_order_lines`.
+ - **Low QA risk**: minimal joins, clear grains, and metrics align with uni2 routing rules (platform ROAS from ad performance tables; unique new customers from executive summary; last-click marketing channel from `sm_utm_source_medium`).
+ - **Complements Batch 1** by adding time-series + refunds + channel-mix + “new customer product” patterns without introducing MTA/experimental tables.
+ - Validation status:
+ - Static schema/column validation: done (0 issues for the canonical page’s SQL blocks).
+ - Live BigQuery dry-run validation (`bq query --dry_run ...`): pending engineering gate.
+
+### Batch 3 (shipped to docs; validated 2026-01-27)
+- Canonical page: `sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`
+- Batch 3 queries added (stumper templates): Q029, Q041, Q019, Q007, Q018
+- Also includes Product Insights section with recursive CTE product combinations query.
+- Why these queries:
+ - They force the most common "gotchas": cohort denominators, first-valid-order anchoring, and choosing cohort-table vs dynamic LTV.
+ - They reuse canonical, documented tables (`sm_transformed_v2`) and keep logic explicit (no implicit "subscription" inference via LIKE).
+ - They're the patterns most likely to improve analyst self-serve and reduce AI Analyst failure modes on LTV/retention.
+- Validation status:
+ - Live BigQuery execution validation: **done** (2026-01-27, `sm-irestore4`)
+ - Batch 3 SQL templates executed successfully and returned plausible results.
+ - Issue found and fixed: Product Combinations query was missing `sku IS NOT NULL` and product-title exclusion filter, causing "Order Specific Details - Not a Product" to pollute results. Fixed by adding standard exclusion pattern.
+
+### Batch 4 (shipped to docs; pending dry-run gate)
+- Added “Attribution & Data Health (diagnostics)” queries DQ01–DQ06.
+- Static schema/column validation: done for the SQL Query Library page (includes `sm_metadata` + `sm_transformed_v2` examples).
+- Live BigQuery dry-run validation: pending engineering gate.
+
+### Batch 5 (shipped to docs; pending dry-run gate)
+- Added “attribution stumpers” queries DQ07–DQ12 (discovery → trend → segmentation → proxy breakouts).
+- Static schema/column validation: done for the SQL Query Library page.
+- Live BigQuery dry-run validation: pending engineering gate.
+
+### Batch 6 (shipped to docs; validated 2026-01-28)
+
+- Shipped in: `4e70af3` (2026-01-28)
+
+Target: common “hard questions” that typically stump people because they require:
+- correct first-valid-order cohorting (`sm_valid_order_index = 1`),
+- careful time-windowing (30/60/90-day horizons),
+- knowing when to use **cohort tables** (CAC + payback) vs **dynamic** order/order-line logic,
+- subscription retention/churn **proxies** (behavioral retention, not billing-system churn).
+
+Batch 6 templates shipped (5):
+1) **Payback period by acquisition source/medium** (cohort table; uses `cost_per_acquisition`)
+2) **LTV:CAC ratio by acquisition source/medium** (cohort table; 6m net LTV vs CAC)
+3) **Repeat purchase rate (paid orders only) within 30/60/90 days by acquisition source/medium** (dynamic; `obt_orders`, filters repeat orders to `order_net_revenue > 0`)
+4) **Repeat purchase rate (paid orders only) within 30/60/90 days by subscription vs one-time first order** (dynamic; `obt_orders`, filters repeat orders to `order_net_revenue > 0`)
+5) **Repeat purchase rate (paid orders only) within 30/60/90 days by first-order AOV bucket** (dynamic; `obt_orders`, filters repeat orders to `order_net_revenue > 0`)
+
+Why these queries:
+- They are “stumpers” that drive frequent confusion and AI Analyst failure modes (cohort anchoring + double counting + horizon logic).
+- They are broadly reusable templates across brands without tenant-specific enumerations.
+- They intentionally exercise the key scalable tables:
+ - cohort table for CAC/payback (`rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`)
+ - order-level analysis (`obt_orders`)
+ - order-level analysis (`obt_orders`)
+
+### Batch 7 (shipped to docs; validated 2026-01-28)
+
+- Shipped in: `4b4e2ac` (2026-01-28)
+
+Target: high-signal investigations that commonly stump analysts when attribution looks “broken” (too much direct/unattributed), or when downstream metrics are skewed by edge-case orders.
+
+Batch 7 templates shipped (7):
+1) **$0 / negative net-revenue order share by source/medium** (diagnostic; `obt_orders`)
+2) **Unattributed share by source system and sales channel** (diagnostic; `obt_orders`)
+3) **Top landing pages for direct traffic orders** (investigation; `obt_orders`)
+4) **Attribution health trend with week-over-week deltas (weekly)** (regression detector; `obt_orders`)
+5) **UTM source/medium discovery (top normalized values, last 90 days)** (exploration; `obt_orders`)
+6) **Join-key coverage trend (weekly missing customer keys + missing SKUs)** (data health; `obt_orders` + `obt_order_lines`)
+7) **Multiple discount codes prevalence (double-counting risk, last 90 days)** (diagnostic; `obt_orders`)
+
+Why these queries:
+- They cover the “what changed?” and “why is attribution weird?” workflows that dashboards usually don’t answer.
+- They are reusable across tenants and avoid hard-coded campaign/source mappings (discovery-first instead).
+- They explicitly surface edge cases that skew analysis (e.g., $0 replacement orders; multiple discount codes).
+
+### Batch 8 (shipped to docs; validated 2026-01-28)
+
+- Shipped in: `0d7acfa` (2026-01-28)
+
+Target: the “hard but common” questions where people mix up attribution dimensions, cohort anchors, and LTV windows (especially when they need order-level + order-line context without double counting).
+
+Batch 8 templates shipped (8):
+1) **90‑day LTV by first-order source/medium (dynamic)** (`obt_orders`)
+2) **90‑day LTV by first-order discount code (single-code only + no-code baseline)** (`obt_orders`)
+3) **First-order refund rate by acquisition source/medium** (`obt_orders`)
+4) **90‑day LTV by first-order source system + sales channel** (`obt_orders`)
+5) **Cohort-table vs dynamic reconciliation (6m vs 180d) for source/medium** (cohort table + `obt_orders`)
+6) **Which initial products lead to the highest 90‑day LTV? (primary first‑order SKU)** (`obt_order_lines` + `obt_orders`)
+7) **90‑day LTV by first-order product type (primary first‑order attribute)** (`obt_order_lines` + `obt_orders`)
+8) **90‑day LTV by first-order product vendor (primary first‑order attribute)** (`obt_order_lines` + `obt_orders`)
+
+Why these queries:
+- They answer exec-level questions customers ask (“which channels bring valuable customers?”) while being explicit about anchors and time windows.
+- They reduce a common failure mode: confusing `source_system` vs `sm_channel` vs `sm_utm_source_medium`.
+- They include a reconciliation template to prevent subtle misreads between precomputed cohort tables and dynamic windowed LTV.
+
+### Batch 9 (shipped to docs; validated 2026-01-28)
+
+- Shipped in: (docs update) 2026-01-28
+- Validation status:
+ - Static schema/column validation: done (`scripts/docs_column_accuracy.py` on `sql-query-library.mdx`)
+ - Live BigQuery dry-run validation: done (2026-01-28, `sm-democo`)
+ - Live BigQuery execution validation: done (2026-01-28, `sm-irestore4` + `sm-piquetea`)
+
+Target: templates for lifecycle messaging analysis, onsite funnel monitoring, and support operations. These are common “who owns this metric?” stumpers because the definitions are platform-specific, event-count based, and often mistaken for causal attribution.
+
+Batch 9 templates shipped (8):
+**Messaging (`rpt_outbound_message_performance_daily`)**
+1) Messaging performance by channel + message type (last 30 days)
+2) Top campaigns by platform-attributed order revenue (last 30 days)
+3) List subscribes vs unsubscribes trend by channel (weekly, last 12 weeks)
+
+**Funnel (`rpt_funnel_events_performance_hourly`)**
+4) Daily funnel step counts + conversion rates (last 30 days)
+5) Top pages by add-to-cart rate (last 7 days)
+6) Funnel conversion by UTM source/medium (last 30 days)
+
+**Customer Support (`obt_customer_support_tickets`)**
+7) Ticket volume + one-touch rate by communication channel (last 30 days)
+8) Resolution time + CSAT coverage by assignee team (last 90 days)
+
+Why these queries:
+- They cover frequently requested operational questions that aren’t answered by the core orders/cohort tables.
+- They force correct interpretation of “platform-attributed” vs “incremental” (messaging) and “events” vs “sessions/users” (funnel).
+- They avoid tenant-specific mappings by using discovery-first and stable dimensions (channel/type/source).
+
+### Batch 10 (shipped to docs; validated 2026-01-29)
+
+- Shipped in: (docs update) 2026-01-29
+- Validation status:
+ - Static schema/column validation: done (`scripts/docs_column_accuracy.py` on `sql-query-library.mdx`)
+ - Live BigQuery dry-run validation: done (2026-01-29, `sm-democo`)
+ - Live BigQuery execution validation: done (2026-01-29, `sm-irestore4` + `sm-piquetea`)
+
+Target: the “definitions + monitoring” questions that cause churn because teams disagree on what the metric means (and because tracking steps are often missing).
+
+Batch 10 templates shipped (6):
+1) **Messaging performance by provider + channel + message type** (`rpt_outbound_message_performance_daily`)
+2) **Flow vs campaign performance trend (weekly)** (`rpt_outbound_message_performance_daily`)
+3) **Funnel tracking health by event source system** (`rpt_funnel_events_performance_hourly`)
+4) **Hourly funnel anomaly detector (hour-over-hour deltas)** (`rpt_funnel_events_performance_hourly`)
+5) **Support backlog aging by team and channel (open tickets)** (`obt_customer_support_tickets`)
+6) **Unread open-ticket share by team and channel** (`obt_customer_support_tickets`)
+
+### Batch 11 (shipped to docs; validated 2026-01-29)
+
+- Shipped in: (docs update) 2026-01-29
+- Validation status:
+ - Static schema/column validation: done (`scripts/docs_column_accuracy.py` on `sql-query-library.mdx`)
+ - Live BigQuery dry-run validation: done (2026-01-29, `sm-democo`)
+ - Live BigQuery execution validation: done (2026-01-29, `sm-irestore4` + `sm-piquetea`)
+
+Target: “meaningfully actionable next questions” after Batches 9–10 (messaging/funnel/support), focused on deliverability diagnostics, creative outliers, and support categorization.
+
+Batch 11 templates shipped (6):
+1) **Deliverability health (bounce + drop rates) by provider and channel (weekly)** (`rpt_outbound_message_performance_daily`)
+2) **Highest click-rate messages (min receives threshold)** (`rpt_outbound_message_performance_daily`)
+3) **Lead-gen to purchase (email signups vs purchases) by UTM source/medium** (`rpt_funnel_events_performance_hourly`)
+4) **Cart drop-off signals (add-to-cart vs remove-from-cart vs checkout) trend (daily)** (`rpt_funnel_events_performance_hourly`)
+5) **Top support tags by volume + one-touch + resolution time** (`obt_customer_support_tickets`)
+6) **Support workload by priority × channel × team** (`obt_customer_support_tickets`)
+
+### Batch 12 (shipped to docs; validated 2026-01-29)
+
+- Shipped in: (docs update) 2026-01-29
+- Validation status:
+ - Static schema/column validation: done (`scripts/docs_column_accuracy.py` on `sql-query-library.mdx`)
+ - Live BigQuery execution validation: done (2026-01-29, `sm-irestore4` + `sm-piquetea`)
+
+Target: lead capture + purchase journey stumpers (event-level lead capture timing + purchase-journey attribution context).
+
+Batch 12 templates shipped (8):
+1) **Lead capture event discovery (top event names, last 30 days)** (`obt_funnel_event_history`)
+2) **Lead capture → first purchase timing (hours) by lead UTM source/medium (last 90 days)** (`obt_funnel_event_history`)
+3) **Lead capture → purchase conversion rate (last 90 days)** (`obt_funnel_event_history`)
+4) **MTA: First-touch vs last-touch marketing channel mix (purchases, last 30 days)** (`sm_experimental.obt_purchase_journeys_with_mta_models`)
+5) **MTA: Time to conversion (days) by first-touch marketing channel (purchases, last 30 days)** (`sm_experimental.obt_purchase_journeys_with_mta_models`)
+6) **MTA landing pages: Top first-touch landing pages by attributed revenue (purchases, last 30 days)** (`sm_experimental.obt_purchase_journeys_with_mta_models`)
+7) **Zero-party attribution: Revenue by post-purchase survey source (new vs repeat, subscription sequence, last 90 days)** (`obt_orders`)
+8) **Last-touch Klaviyo orders: New vs repeat × subscription sequence (last 90 days)** (`obt_orders`)
+
+## Query Entry Format (Canonical Metadata)
+
+Each query should have consistent metadata so it can be searched, deduped, and QA’d.
+
+Phased approach (avoid upfront overhead):
+
+### v0 (Batches 1–2): minimal required fields
+- `id`: stable identifier (we can start with eval IDs like `Q011` and later alias to `QL-*` if needed)
+- `title`
+- `domain`
+- `primary_table`
+- `sql` (docs-ready placeholders)
+- `notes` (only when caveats are important)
+- `source_artifacts_path` (e.g., `uni-training/questions_grouped/unique/Q011_.../artifacts/generated-queries.sql`)
+
+### v1+ (Batch 3 onward): add structure once patterns emerge
+- `archetype`, `time_grain`, `default_timeframe`, `tags`, `example_questions`, `validation_checks`
+
+## Archetypes (Reusable Building Blocks)
+
+We standardize common shapes to maximize reuse:
+
+- `trend`: metric over time + optional period-over-period (PoP) comparison
+- `breakdown`: metric by dimension (`sm_channel`, `source_system`, `sm_store_id`)
+- `ranking`: top-N entities (products, campaigns, customers) with thresholds
+- `cohort_curve`: retention/LTV over months since acquisition
+- `funnel`: session/event funnel steps with conversion rates (when available)
+- `diagnostic`: data freshness / attribution health / null-coverage checks
+- `exploration`: distinct-value discovery query used before exact matches
+
+## Prioritization (How We Pick the Next Batch)
+
+We prioritize with a scoring rubric per candidate query:
+
+1) **User value / frequency**: how often this comes up (use eval dataset + support intuition)
+2) **Template reusability**: can it answer multiple phrasings with small parameter tweaks?
+3) **Low QA risk**: minimal joins, stable columns, clear semantics
+4) **Docs placement value**: would a customer actually copy/paste this from a table page?
+
+Practical batch selection rule:
+- Each batch should cover **2–3 archetypes** and **1–2 primary tables** max.
+- First batches should skew heavily toward:
+ - `obt_orders` / `dim_orders` / `obt_order_lines`
+ - plus one “adjacent” table when needed (e.g., `rpt_executive_summary_daily`).
+
+Seed evidence we already have:
+- The `questions_grouped/unique/` set is concentrated in Orders/Order Lines/Order Dims, then CAC/ROAS, then cohort/MTA.
+- It includes deprecated `sm_experimental.rpt_mta_models_v4` references; those must not be promoted to “gold”.
+
+## QA + Validation Workflow (Batch-Based)
+
+### Step 0 — Candidate selection
+- Pick 5–10 candidates using the rubric.
+- Decide publication targets:
+ - AI Analyst Query Library domain page(s)
+ - Specific table pages (if applicable)
+
+### Step 1 — Normalize to docs conventions
+- Prefer extracting directly from the eval artifacts first:
+ - `uni-training/questions_grouped/unique/Q*/artifacts/generated-queries.sql`
+ - If present, compare with `generated-queries_revised.sql` and choose the best starting point.
+- Replace literal project IDs with `your_project`.
+- Ensure tables are `sm_transformed_v2` unless explicitly experimental.
+- Add assumptions header.
+- Ensure `is_order_sm_valid = TRUE` is present where required.
+- Remove/avoid deprecated tables (e.g., `sm_experimental.rpt_mta_models_v4`).
+
+### Step 2 — Static validation (CI-friendly)
+We can validate without warehouse access:
+
+- **Schema/column validation**:
+ - Use existing script: `sourcemedium-docs/scripts/docs_column_accuracy.py` (extend or reuse) to validate SQL blocks reference real columns for referenced tables.
+- **Style + rule linting** (new checks; should mirror uni2 constraints):
+ - enforce assumptions header
+ - ban LIKE/REGEXP on categorical columns (or require a “discovery query” pattern first)
+ - enforce dataset naming (`your_project.sm_transformed_v2`)
+ - enforce required filters for orders tables (`is_order_sm_valid = TRUE`)
+
+### Step 3 — Live validation (engineer-run gate)
+- Run BigQuery dry-run for each query example (per docs repo guidance):
+ - `bq query --dry_run --use_legacy_sql=false --project_id=sm-uni ""`
+- When feasible, run the query with a constrained timeframe and `LIMIT` to verify it returns plausible results.
+
+### Step 4 — Human QA checklist
+- Semantics:
+ - `source_system` vs `sm_channel` usage correct
+ - revenue definition consistent (prefer `order_net_revenue` unless explicitly otherwise)
+ - time bucket derivations correct (BigQuery GoogleSQL)
+- Safety:
+ - no invented columns
+ - no categorical LIKE/REGEXP
+ - required validity filters present
+- UX:
+ - query answers a real question and is easily adaptable
+ - notes mention how to scope by store/channel safely
+
+### Step 5 — Publish
+- Add to:
+ - domain query library page(s)
+ - relevant table pages (“Example Queries” section)
+- Keep each page scannable with consistent formatting:
+ - “When to use”
+ - “SQL”
+ - “How to adapt” (optional)
+ - “Common pitfalls” (optional)
+
+## Batch 1 Recommendation (Initial “Gold” Set)
+
+Target: high ROI, low risk, core tables, directly extractable from eval artifacts.
+
+Concrete, immediately-actionable candidates (from `questions_grouped/unique/`):
+
+| # | Question | Seed ID | Domain | Archetype | Primary table |
+|---|----------|---------|--------|-----------|---------------|
+| 1 | What is my average CAC? | Q011 | Marketing & Ads | breakdown | `rpt_executive_summary_daily` |
+| 2 | Which platform and campaign type has the highest ROAS? | Q001 | Marketing & Ads | ranking | `rpt_ad_performance_daily` |
+| 3 | Which source/mediums are driving repeat purchases? | Q021 | Customers / Retention | breakdown | `obt_orders` |
+| 4 | What percentage of our orders are first-time vs repeat? | Q022 | Customers | breakdown | `obt_orders` |
+| 5 | How has the ratio of new to repeat customers changed? | Q003 | Customers | trend | `rpt_executive_summary_daily` |
+| 6 | What are the top 10 products by net revenue? | Q119 | Products | ranking | `obt_order_lines` |
+| 7 | What’s the average order value by marketing channel? | Q060 | Revenue / Attribution | breakdown | `obt_orders` |
+| 8 | Let’s define current revenue as last 30 days (and compare) | Q023 | Orders & Revenue | trend | `obt_orders` |
+
+Batch size flexibility:
+- Start with 5–8 if we want fast iteration; expand to 10 once the publish + QA loop is smooth.
+
+Expected normalization notes for Batch 1:
+- Q021/Q060 involve UTMs / source-medium dimensions; ensure uni2-safe categorical handling (avoid LIKE/REGEXP; consider a discovery-first pattern if needed).
+
+## Batch 2 (shipped)
+
+Target: add time-series + refunds + product discovery patterns with minimal QA risk.
+
+Status: shipped; live BQ validation passed (2026-01-28, `sm-irestore4`).
+
+Candidates shipped as Batch 2:
+- Q081 — ROAS trends over time (Marketing & Ads; `rpt_ad_performance_daily`)
+- Q082 — customer acquisition trends over time (Customers; `rpt_executive_summary_daily`)
+- Q083 — top products by units sold (Products; `obt_order_lines`)
+- Q017 — products most common with new customers (Products/Customers; `obt_order_lines` + `sm_valid_order_index = 1`)
+- Q062 — refund rate by marketing channel (Refunds/Attribution; `obt_orders` + refund fields)
+- Q115 — distribution of orders/revenue by sales channel (Sales channels; `obt_orders`)
+
+Notes (what we changed vs eval artifacts):
+- Q081/Q082 eval artifacts referenced non-canonical datasets (`sm_experimental.*`, `sm_views.*`). We rewrote to canonical `sm_transformed_v2` tables that match uni2 routing rules.
+- Q062 eval artifact used `sm_channel` for “marketing channel”. We rewrote to use `sm_utm_source_medium` (last-click) per uni2 attribution semantics.
+
+## Batch 3 (shipped — “stumper queries”)
+
+Target: expand coverage to questions that routinely stump analysts because they require:
+- first-valid-order anchoring,
+- careful cohort definitions / denominators,
+- choosing between **precomputed cohort tables** vs **dynamic LTV** from `obt_orders`/`obt_order_lines`,
+- subscription retention semantics (customer-level retention proxy, not subscription-billing-system churn).
+
+Status: shipped; live BQ validation passed (2026-01-28, `sm-irestore4`).
+
+Batch size: 5–10, but expect higher QA effort per query.
+
+### Primary candidates (recommended for Batch 3)
+
+1) **LTV by first-purchased SKU / product (dynamic, uses order lines)**
+ - Question archetype: “Which initial products create the highest 90‑day LTV?”
+ - Table(s): `obt_order_lines` (for SKU/product) + `obt_orders` (for first-order anchor if needed)
+ - Key requirements:
+ - anchor cohort on first **valid** order (`sm_valid_order_index = 1`)
+ - define horizon (30/60/90 days) and compute per customer then aggregate by SKU
+ - include sample-size guard (`customers >= 10` or higher)
+
+2) **LTV by first-order attribute (dynamic, uses orders)**
+ - Question archetype: “What is 90‑day LTV by acquisition source/medium (or discount code / landing page)?”
+ - Table(s): `obt_orders` (preferred when the attribute exists at order level)
+ - Key requirements:
+ - anchor cohort on first **valid** order (`sm_valid_order_index = 1`)
+ - use `order_net_revenue` as default LTV metric unless the question specifies otherwise
+
+3) **Retention % by acquisition source/medium (precomputed cohort table)**
+ - Question archetype: “How does 3‑month / 6‑month retention vary by acquisition channel?”
+ - Table: `rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ - Key requirements:
+ - filter `acquisition_order_filter_dimension = 'source/medium'`
+ - **must include** `sm_order_line_type = 'all_orders'` to avoid double counting
+ - compute retention as `customer_count / cohort_size` at `months_since_first_order = N`
+ - include cohort-size guards (`cohort_size >= 10` minimum; prefer `>= 50` for ranked outputs)
+
+4) **Discount-code cohorts: retention + LTV (precomputed cohort table)**
+ - Question archetype: “Which discount codes acquire higher-retention customers?”
+ - Table: `rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ - Key requirements:
+ - filter `acquisition_order_filter_dimension = 'discount_code'`
+ - `sm_order_line_type = 'all_orders'` (no double counting)
+ - discovery-first if discount codes are messy (enumerate top codes by cohort_size, then analyze)
+
+5) **Subscription vs one-time: retention + LTV comparison (precomputed cohort table)**
+ - Question archetype: “How much more valuable are subscription customers vs one-time?”
+ - Table: `rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters`
+ - Key requirements:
+ - be explicit whether we mean:
+ - **first-order type** cohorts (use `acquisition_order_filter_dimension = 'order_type_(sub_vs._one_time)'`), or
+ - **lifetime behavior** subsets (use `sm_order_line_type IN ('subscription_orders_only','one_time_orders_only')`)
+ - never aggregate across `sm_order_line_type` without filtering (triple-count risk)
+
+### Secondary candidates (pick 0–3 if we want 8–10 in Batch 3)
+
+- Contribution profit trend by channel (`rpt_executive_summary_daily`, time series).
+- Payback period proxy (cohort LTV + CAC scalar):
+ - Use cohort table for marketing acquisition dimensions; add CAC from `rpt_executive_summary_daily` at matching grain.
+- Purchase interval distribution for non-subscribers (orders; window functions, careful filters).
+
+### Reference guidance (useful, but uni2 wins on conflicts)
+- Uni2 authoritative routing + rules: `src/agent_core/agents/prompts.py`
+- Cohort-table cautions (double-counting; dimensions): `uni-training/.claude/shared/MODEL_KNOWLEDGE.md`
+
+## Batch 4 + 5 (merged, shipped — attribution + data health)
+
+Status: shipped; live BQ validation passed (2026-01-28, `sm-irestore4`).
+
+Target: attribution coverage + data health diagnostics ("why is everything direct / missing?") plus actionable follow-up patterns.
+
+Notes:
+- `dim_data_dictionary` lives in `your_project.sm_metadata.dim_data_dictionary` (not `sm_transformed_v2`).
+- We removed redundant queries (DQ03/DQ07 source/medium snapshots redundant with DQ06 trend view).
+- Fixed click-id coverage query to exclude `'(none)'` placeholder values.
+- Removed DQ## prefixes from titles for readability.
+
+Final queries shipped (10 data health queries):
+1. Which tables are stale or missing data? (`sm_metadata.dim_data_dictionary`)
+2. Attribution column coverage on orders (`sm_metadata.dim_data_dictionary`)
+3. When UTMs are missing, what other attribution signals exist? (`obt_orders`)
+4. Top referrer domains for orders missing UTMs (`obt_orders`)
+5. Key join-key completeness (customers + SKU coverage) (`obt_orders` + `obt_order_lines`)
+6. Attribution health trend (weekly) (`obt_orders`)
+7. Attribution health by store and sales channel (`obt_orders`)
+8. Discount code parsing (top codes by revenue) (`obt_orders`)
+9. Top landing pages for orders missing UTMs (`obt_orders`)
+10. Click-id coverage vs UTM coverage (gclid/fbclid) (`obt_orders`)
+
+## Handling “Discovery-First” Without Breaking uni2 Rules
+
+Some analyses (especially UTMs) are high-entropy in practice. To stay aligned with uni2’s “no categorical LIKE/REGEXP” rule, doc examples should prefer:
+
+- A small **exploration query** to enumerate actual distinct values (recent window, top by frequency).
+- A final query that uses **exact matches / IN** with normalized comparisons.
+
+This also avoids embedding tenant-specific value assumptions in docs.
+
+## Success Metrics (What “Good” Looks Like)
+
+- We can consistently ship 5–10 “gold” queries per batch with low churn.
+- Docs examples pass static schema checks and dry-run checks.
+- The AI Analyst produces fewer SQL retries / QA failures on the same archetypes.
+- Coverage improves against the eval set (e.g., % of eval questions matched to a “gold” archetype).
+
+## Open Questions
+
+1) Source of truth (decision):
+ - Canonical “gold” queries live in `sourcemedium-docs/` (these are documentation artifacts). Uni2 can optionally consume them later, but docs should own validation + publication.
+2) “Gold” vs “Draft”:
+ - Do we publish drafts in docs (clearly marked), or keep drafts internal until validated?
+3) MTA sequencing:
+ - When do we start including MTA examples (explicit intent only), and how do we label experimental limitations?
+
+## v0 Exit Criteria (Ship Gate)
+
+We consider v0 shipped when:
+- ≥ 10 queries are published on the canonical SQL page (`sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`),
+- each new query passes BigQuery dry-run against a real project (`--project_id=sm-uni`) before placeholder rewrite,
+- each query has engineering QA sign-off,
+- at least 3 core table pages have updated “Example Queries” sections (recommended: `obt_orders`, `dim_orders`, `obt_order_lines`).
+
+## Table Preference (One-liners)
+
+- Prefer `obt_orders` for order-level aggregations where you want the wide “analytics-ready” order fields (revenue/profit/refunds/channel context) with minimal joins.
+- Prefer `dim_orders` when you specifically need order sequencing fields like `sm_valid_order_index` for new vs repeat logic and other “dimension” attributes.
diff --git a/specs/ragie-spec.md b/specs/ragie-spec.md
new file mode 100644
index 0000000..f25e567
--- /dev/null
+++ b/specs/ragie-spec.md
@@ -0,0 +1,567 @@
+# Ragie Docs Indexing + Tenant Partition Retrieval Spec
+
+Status: Proposed
+Owner: Docs + AI Analyst
+Last updated: 2026-02-06
+
+## 1) Goal
+
+Create a production-ready Ragie indexing and retrieval pipeline for SourceMedium docs that:
+
+1. Auto-indexes docs from this repo on push.
+2. Supports idempotent upsert and stale-doc deletion.
+3. Enforces strict tenant isolation with Ragie partitions.
+4. Exposes retrieval primitives we can use to "RAG out" answers safely.
+
+## 2) Scope
+
+### In scope
+
+- Index published docs from this repo into Ragie.
+- Use Ragie REST API directly (no CLI dependency in v1).
+- Add tenant-partition retrieval contract (`partition = tenant_id mapping`).
+- Enable partition context-aware retrieval metadata (`description`, `context_aware`, `metadata_schema`).
+- Enable partition-scoped entity extraction instructions for docs.
+- Define automation workflow and acceptance tests.
+
+### Out of scope (v1)
+
+- UI work in docs dashboard.
+- Migrating historical non-doc knowledge sources.
+- Building full answer orchestration in this repo (we define API contract only).
+
+## 3) Verified Ragie API Contract (Source of Truth)
+
+Base URL: `https://api.ragie.ai`
+Auth: `Authorization: Bearer `
+
+OpenAPI confirms:
+
+- `POST /documents` (multipart file upload)
+- `POST /documents/raw` (ingest raw text/JSON)
+- `POST /documents/url`
+- `GET /documents` (paginated list)
+- `GET /documents/{document_id}` (status/details)
+- `PUT /documents/{document_id}/raw`
+- `PUT /documents/{document_id}/file`
+- `PATCH /documents/{document_id}/metadata`
+- `DELETE /documents/{document_id}`
+- `POST /retrievals`
+- `GET/POST /partitions`, `GET/PATCH/DELETE /partitions/{partition_id}`
+- `GET/POST /instructions`, `PUT/DELETE /instructions/{instruction_id}`
+- `GET /documents/{document_id}/entities`
+- `GET /instructions/{instruction_id}/entities`
+
+Document lifecycle states (from endpoint docs):
+
+- `pending`
+- `partitioning`
+- `partitioned`
+- `refined`
+- `chunked`
+- `indexed`
+- `summary_indexed`
+- `keyword_indexed`
+- `ready`
+- `failed`
+
+## 4) Constraints From This Repo
+
+- This repo is mostly `.mdx` pages (`316` files), with very few `.md` files.
+- Ragie file upload supports `.md` but does not list `.mdx` as a supported file extension.
+
+Decision:
+
+- Use `POST /documents/raw` and `PUT /documents/{id}/raw` for v1 indexing.
+- Convert MDX source into clean text before upload.
+
+This avoids extension mismatch risk and gives deterministic content shaping.
+
+## 5) Partition Strategy (Tenant Isolation)
+
+### Hard requirements
+
+- Every write MUST include `partition`.
+- Every retrieval MUST include `partition`.
+- The partition MUST be server-derived from authenticated tenant context.
+- Never trust client-provided partition directly.
+- Any docs under `/tenants/` MUST be hard partitioned:
+ - `tenants/...` docs are only indexed into `tenant_`
+ - shared/non-tenant partitions must never contain `/tenants/` docs
+
+OpenAPI behavior note:
+
+- If `partition` is omitted, account behavior differs by account age (accounts created after 2025-01-09 default-scope, older accounts may scope more broadly unless configured).
+- Because of this ambiguity, our implementation treats missing partition as a hard error.
+
+### Partition format
+
+- Regex: `^[a-z0-9_-]+$` (matches Ragie rules)
+- Canonical form: `tenant_`
+
+Examples:
+
+- `tenant_acme`
+- `tenant_12345`
+
+### Shared docs behavior
+
+Two supported modes:
+
+1. Strict tenant-only mode (default for security-sensitive workflows):
+ - Query only `tenant_`.
+ - Guarantees no cross-tenant retrieval.
+2. Tenant + shared fallback mode (optional):
+ - First query `tenant_`.
+ - If no useful chunks, query `shared_docs`.
+ - Keep responses labeled by source partition.
+
+If we need shared docs visible in strict mode, duplicate shared docs into each tenant partition during provisioning.
+
+## 6) Document Identity + Metadata Contract
+
+### Identity
+
+- `external_id` is required in practice for idempotent sync.
+- Use a stable, partition-safe value:
+ - `external_id = "repo:sourcemedium-docs|partition:|ref:"`
+
+### Name
+
+- Use stable path-like name, not title:
+ - `name = `
+
+This avoids rename churn when titles change.
+
+### Metadata keys (custom)
+
+- `source`: `sourcemedium-docs`
+- `repo`: `sourcemedium-docs`
+- `docs_ref`: `data-activation/template-resources/sql-query-library`
+- `url_path`: `/data-activation/template-resources/sql-query-library`
+- `url_full`: `https://docs.sourcemedium.com/data-activation/template-resources/sql-query-library`
+- `title`: frontmatter title
+- `description`: frontmatter description
+- `content_hash`: sha256 of normalized text
+- `commit_sha`: git SHA used for sync
+- `visibility`: `tenant` or `shared`
+- `tenant_id`: normalized tenant id (for tenant partitions)
+
+Do not use Ragie reserved keys:
+
+- `document_id`
+- `document_type`
+- `document_source`
+- `document_name`
+- `document_uploaded_at`
+- `start_time`
+- `end_time`
+- `chunk_content_type`
+
+## 7) Ingestion Input Selection
+
+### Source of truth for pages
+
+Use `docs.json` navigation references, not a blind filesystem glob.
+
+Reason:
+
+- Only published pages should be indexed.
+- Prevent indexing orphan/internal files unintentionally.
+
+### Inclusion
+
+- Paths referenced by `docs.json` that resolve to `.mdx` or `.md`.
+
+### Exclusion
+
+- `snippets/`
+- `specs/`
+- hidden/internal operational files
+
+## 8) MDX Normalization Rules (for `/documents/raw`)
+
+Input: raw `.mdx` file
+Output: deterministic plain text optimized for retrieval
+
+Normalization pipeline:
+
+1. Parse frontmatter.
+2. Build preamble:
+ - `# `
+ - ``
+3. Remove frontmatter block from body.
+4. Remove `import` / `export` lines.
+5. Convert known Mintlify callouts:
+ - `...` -> `Info: ...`
+ - `...` -> `Tip: ...`
+ - `...` -> `Note: ...`
+ - `...` -> `Warning: ...`
+6. Strip remaining JSX tags while keeping textual children.
+7. Preserve headings, lists, code fences, and links.
+8. Normalize whitespace and line endings.
+
+Store `content_hash` of final normalized text in metadata.
+
+## 9) Sync Algorithm (Idempotent)
+
+Per partition sync run:
+
+1. Optionally ensure partition config with `PATCH /partitions/{partition_id}`:
+ - `context_aware = true`
+ - `description` (partition summary)
+ - `metadata_schema` (filter-friendly schema for our metadata keys)
+2. Optionally ensure entity instruction exists (`POST /instructions`) scoped to partition.
+3. Load local docs set from `docs.json`.
+4. Normalize each local doc to text.
+5. Build local map by `external_id`.
+6. Fetch all remote docs in partition via `GET /documents` pagination.
+7. Build remote map by `external_id` (client-side filter `metadata.source == sourcemedium-docs`).
+8. For each local doc:
+ - Not in remote -> `POST /documents/raw`.
+ - In remote and hash changed -> `PUT /documents/{id}/raw`.
+ - In remote and metadata changed -> `PATCH /documents/{id}/metadata`.
+9. For each remote doc absent locally -> `DELETE /documents/{id}?async=true`.
+10. Poll changed docs (`GET /documents/{id}`) until terminal:
+ - success: `ready` (or optionally `indexed` for faster CI)
+ - failure: `failed` -> fail job with doc id + errors.
+
+## 10) GitHub Actions Design
+
+Workflow file: `.github/workflows/ragie-index.yml`
+
+Triggers:
+
+- `push` to `main`/`master` when docs files or `docs.json` change.
+- `workflow_dispatch` with inputs:
+ - `partition` (default `shared_docs`)
+ - `mode` (`incremental`/`full`)
+ - `doc_ref` (optional single page)
+ - `ensure_partition_context_aware` (`true/false`)
+ - `ensure_entity_instruction` (`true/false`)
+
+Secrets and vars:
+
+- Secret: `RAGIE_API_KEY`
+- Variable (or workflow input): `RAGIE_PARTITION`
+- Optional vars: `RAGIE_ENSURE_PARTITION_CONTEXT_AWARE`, `RAGIE_ENSURE_ENTITY_INSTRUCTION`
+
+Execution steps:
+
+1. Checkout repo.
+2. Set up Python runtime.
+3. Install script deps (minimal stdlib + `requests` + frontmatter parser).
+4. Run shared (or input-selected) partition sync:
+ - `python scripts/ragie_sync.py --partition "$RAGIE_PARTITION" --mode incremental --ensure-partition-context-aware --ensure-entity-instruction`
+5. On push, detect changed tenant slugs from `tenants/**` paths and run:
+ - `python scripts/ragie_sync.py --partition "tenant_" --mode incremental --ensure-partition-context-aware --ensure-entity-instruction`
+
+For tenant-specific sync jobs (if we run them in CI):
+
+- one run per tenant partition, or
+- one orchestrator job that iterates tenant list from secure source.
+
+## 11) Retrieval Contract (App Side)
+
+### API request to Ragie
+
+`POST /retrievals`
+
+Body (minimum):
+
+- `query` (required)
+- `partition` (required by our policy)
+
+Recommended defaults:
+
+- `top_k = 8`
+- `rerank = true`
+- `max_chunks_per_document = 2`
+- `recency_bias = false`
+
+Optional `filter` supports metadata operators:
+
+- `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`
+
+### Retrieval wrapper requirements
+
+Our server wrapper MUST:
+
+1. Derive `partition` from authenticated tenant context.
+2. Reject requests with missing tenant context.
+3. Never allow arbitrary partition override from client payload.
+4. Log request id, tenant id, partition, top_k, latency, chunk count.
+
+### Context-aware partition requirements
+
+For each active partition, keep these fields set:
+
+- `context_aware = true`
+- `description` with concise scope summary
+- `metadata_schema` describing filterable metadata keys (`content_type`, `primary_surface`, `surfaces`, `topic_tags`, etc.)
+
+This improves Ragie’s dynamic filter-generation quality when using metadata-driven retrieval.
+
+### Entity extraction requirements
+
+- Create one partition-scoped instruction:
+ - `name`: deterministic (`sourcemedium-doc-entities-v1-`)
+ - `scope`: `document`
+ - `partition`: target partition
+ - `filter`: `{source == sourcemedium-docs, repo == sourcemedium-docs}`
+ - `entity_schema`: arrays for `surfaces`, `keywords`, `table_names`, `column_names`, `dashboard_modules`, `integration_platforms`
+- Read extracted entities via:
+ - `GET /documents/{document_id}/entities`
+ - `GET /instructions/{instruction_id}/entities`
+
+### Expected response fields from Ragie
+
+`scored_chunks[]` includes:
+
+- `text`
+- `score`
+- `id`
+- `index`
+- `document_id`
+- `document_name`
+- `document_metadata`
+- `links`
+
+## 12) Answer Generation Strategy
+
+### Preferred (v1)
+
+- Use Ragie retrieval + our LLM completion layer.
+- Pass top chunks with citations (`document_name`, `url_full` metadata).
+
+### Optional (v2)
+
+- Evaluate Ragie `POST /responses` for native generated answers.
+- Constraint: current model support in docs is `deep-search`.
+
+## 13) Security Requirements
+
+1. `RAGIE_API_KEY` only in secrets manager / CI secret.
+2. Never expose API key in client-side code.
+3. Partition is mandatory on write/read.
+4. Enforce tenant->partition mapping server-side.
+5. Add alerting on retrievals missing partition (should be zero).
+
+## 14) Observability + Ops
+
+Track metrics:
+
+- docs indexed created/updated/deleted per run
+- indexing latency to `ready`
+- failed document count + ids
+- retrieval latency p50/p95
+- empty retrieval rate by tenant
+- cross-partition leakage test pass rate
+
+Operational playbooks:
+
+- Backfill: run `workflow_dispatch` with `mode=full`.
+- Reindex single doc: script flag `--doc-ref `.
+- Partition cleanup: `DELETE /partitions/{partition_id}` only by admin workflow.
+
+## 15) Acceptance Criteria
+
+### Indexing
+
+1. Push changing one doc updates exactly one Ragie document in target partition.
+2. Deleting a doc removes the corresponding Ragie document.
+3. No duplicate active documents for same `external_id` + partition.
+4. Failed indexing returns non-zero CI exit.
+
+### Multi-tenancy
+
+1. Doc ingested into `tenant_a` is not retrievable from `tenant_b`.
+2. Retrieval requests without partition are rejected by our wrapper.
+3. Tenant partition names always satisfy `^[a-z0-9_-]+$`.
+4. Docs under `/tenants/` never appear in `shared_docs`.
+
+### Partition intelligence
+
+1. Partition has `context_aware=true` after sync bootstrap.
+2. Partition description and metadata schema match expected template.
+3. Partition-scoped instruction exists and is active.
+
+### Entity extraction
+
+1. New/updated docs in partition produce entities for the configured instruction.
+2. Entity payload validates against configured `entity_schema`.
+
+### Retrieval quality
+
+1. Top chunks include correct `url_full` citation metadata.
+2. Known test queries return at least one relevant chunk.
+
+## 16) Implementation Plan
+
+### Phase 1: Core sync script
+
+- Add `scripts/ragie_sync.py` with:
+ - docs.json page discovery
+ - MDX normalization
+ - create/update/delete sync
+ - polling + failure reporting
+
+### Phase 2: CI automation
+
+- Add `.github/workflows/ragie-index.yml`.
+- Add secret wiring docs in README/ops notes.
+
+### Phase 3: Retrieval wrapper integration
+
+- Add server-side retrieval client in app repo.
+- Enforce tenant->partition mapping middleware.
+
+### Phase 4: Validation + canary
+
+- Run shared partition backfill.
+- Run tenant canary partitions.
+- Validate isolation test suite before production enablement.
+
+## 17) cURL Reference Examples
+
+### Create raw document in tenant partition
+
+```bash
+curl --request POST \
+ --url https://api.ragie.ai/documents/raw \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header 'Content-Type: application/json' \
+ --data @- <<'JSON'
+{
+ "name": "onboarding/getting-started/intro-to-sm",
+ "external_id": "repo:sourcemedium-docs|partition:tenant_acme|ref:onboarding/getting-started/intro-to-sm",
+ "partition": "tenant_acme",
+ "metadata": {
+ "source": "sourcemedium-docs",
+ "repo": "sourcemedium-docs",
+ "docs_ref": "onboarding/getting-started/intro-to-sm",
+ "url_full": "https://docs.sourcemedium.com/onboarding/getting-started/intro-to-sm",
+ "content_hash": ""
+ },
+ "data": "# Intro to SourceMedium\\n...normalized content..."
+}
+JSON
+```
+
+### Retrieve with strict tenant partition
+
+```bash
+curl --request POST \
+ --url https://api.ragie.ai/retrievals \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header 'Content-Type: application/json' \
+ --data @- <<'JSON'
+{
+ "query": "How do I install the SDK?",
+ "partition": "tenant_acme",
+ "top_k": 8,
+ "rerank": true,
+ "max_chunks_per_document": 2
+}
+JSON
+```
+
+### Poll status for a changed document
+
+```bash
+curl --request GET \
+ --url "https://api.ragie.ai/documents/" \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header "partition: tenant_acme"
+```
+
+### Delete stale document
+
+```bash
+curl --request DELETE \
+ --url "https://api.ragie.ai/documents/?async=true" \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header "partition: tenant_acme"
+```
+
+### Enable context-aware partition settings
+
+```bash
+curl --request PATCH \
+ --url "https://api.ragie.ai/partitions/tenant_acme" \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header 'Content-Type: application/json' \
+ --data @- <<'JSON'
+{
+ "context_aware": true,
+ "description": "SourceMedium tenant documentation partition for acme.",
+ "metadata_schema": {
+ "type": "object",
+ "properties": {
+ "content_type": {"type": "string"},
+ "primary_surface": {"type": "string"},
+ "surfaces": {"type": "array", "items": {"type": "string"}},
+ "topic_tags": {"type": "array", "items": {"type": "string"}}
+ }
+ }
+}
+JSON
+```
+
+### Create partition-scoped entity extraction instruction
+
+```bash
+curl --request POST \
+ --url https://api.ragie.ai/instructions \
+ --header "Authorization: Bearer $RAGIE_API_KEY" \
+ --header 'Content-Type: application/json' \
+ --data @- <<'JSON'
+{
+ "name": "sourcemedium-doc-entities-v1-tenant_acme",
+ "active": true,
+ "scope": "document",
+ "partition": "tenant_acme",
+ "filter": {
+ "source": {"$eq": "sourcemedium-docs"},
+ "repo": {"$eq": "sourcemedium-docs"}
+ },
+ "prompt": "Extract analytics support entities...",
+ "entity_schema": {
+ "type": "object",
+ "properties": {
+ "surfaces": {"type": "array", "items": {"type": "string"}},
+ "keywords": {"type": "array", "items": {"type": "string"}}
+ }
+ }
+}
+JSON
+```
+
+## 18) Risks and Mitigations
+
+1. MDX component noise hurts retrieval quality.
+ - Mitigation: normalization pipeline before `/documents/raw`.
+2. Missing partition leads to accidental broad reads on older Ragie accounts.
+ - Mitigation: hard fail when partition missing in our wrapper and sync scripts.
+3. Duplicate docs from historical runs.
+ - Mitigation: stable `external_id` + dedupe step in sync.
+4. Long indexing tails for large updates.
+ - Mitigation: async delete + bounded polling + retry/backoff.
+
+## 19) Final Decision Log
+
+1. Use Ragie REST API directly for v1 (`/documents/raw`, `/retrievals`) instead of CLI.
+2. Use partition as mandatory tenant boundary.
+3. Use docs.json-driven page discovery.
+4. Use idempotent upsert + stale-delete sync model.
+5. Keep answer generation outside this repo for v1 (retrieval contract first).
+
+## 20) References
+
+- Ragie Getting Started: `https://docs.ragie.ai/docs/getting-started`
+- Ragie Create Document reference: `https://docs.ragie.ai/reference/createdocument`
+- Ragie Retrieve reference: `https://docs.ragie.ai/reference/retrieve`
+- Ragie Partitions guide: `https://docs.ragie.ai/docs/partitions`
+- Ragie Context-Aware Descriptions: `https://docs.ragie.ai/docs/context-aware-descriptions`
+- Ragie Entity Extraction guide: `https://docs.ragie.ai/docs/entity-extraction`
+- Ragie OpenAPI schema used for endpoint/field validation: `https://api.ragie.ai/openapi.json`
diff --git a/specs/user-facing-agent-skill-spec.md b/specs/user-facing-agent-skill-spec.md
new file mode 100644
index 0000000..b7547b7
--- /dev/null
+++ b/specs/user-facing-agent-skill-spec.md
@@ -0,0 +1,282 @@
+# User-Facing Agent Skill Spec (SourceMedium BigQuery)
+
+Status: Proposed (finalized v1 decisions)
+Owner: Docs + AI Analyst + Data Platform
+Last updated: 2026-02-08
+
+## 1) Goal
+
+Define one public, user-facing skill that helps tenants/end users:
+
+1. Set up BigQuery CLI access.
+2. Verify project and dataset/table access.
+3. Ask analytical questions with auditable SQL receipts.
+4. Ground explanations in SourceMedium docs and real schema/runtime constraints.
+
+The skill must work across **Codex** and **Claude Code**.
+
+## 2) Final v1 Decisions
+
+1. **Single skill first**: ship `sm-bigquery-analyst`.
+2. **Canonical host is not the docs site**:
+ - Canonical machine-readable artifact lives in a dedicated/public GitHub skills repo.
+ - Docs site hosts human-facing pages and install instructions only.
+3. **Agent Skills spec compliance is mandatory**:
+ - Required frontmatter fields and naming constraints must pass validation.
+4. **skills.sh publication path**:
+ - Publish from GitHub repo.
+ - Provide install commands in docs.
+ - Leaderboard listing is automatic based on `npx skills add` telemetry.
+
+## 3) Scope
+
+### In scope
+
+1. User setup flow (`gcloud`/`bq`, auth, project selection, access checks).
+2. Querying and analysis workflow with strict output contract.
+3. Docs-first guidance using canonical SourceMedium pages.
+4. Access-escalation workflow with exact copy/paste admin request template.
+5. Internal grounding via generated references from `reporting_queries` and `uni`.
+6. Packaging for Codex + Claude compatibility.
+
+### Out of scope (v1)
+
+1. IAM provisioning automation.
+2. Production table mutation by default.
+3. Replacing `uni` tool orchestration.
+4. Multi-skill public taxonomy.
+
+## 4) Convention: Where This Lives
+
+### 4.1 Canonical machine-readable location
+
+Use a skill repo structure:
+
+```text
+/
+└── skills/
+ └── sm-bigquery-analyst/
+ ├── SKILL.md
+ ├── references/
+ ├── scripts/
+ ├── assets/ # optional
+ └── agents/openai.yaml # optional, Codex-facing metadata
+```
+
+This is the source for installation and distribution.
+
+### 4.2 Docs-site location (human-facing)
+
+Add docs pages under a dedicated section (for example `AI Analyst -> Agent Skills`):
+
+1. `ai-analyst/agent-skills/index.mdx` (overview + skill catalog)
+2. `ai-analyst/agent-skills/sm-bigquery-analyst.mdx` (what it does + install commands + examples)
+
+Docs pages are explanatory. They should not be treated as canonical SKILL source.
+
+## 5) Agent Skills Spec Compliance Requirements
+
+`SKILL.md` must include YAML frontmatter with:
+
+1. Required:
+ - `name`
+ - `description`
+2. Optional:
+ - `license`
+ - `compatibility`
+ - `metadata`
+ - `allowed-tools` (experimental)
+
+Hard constraints:
+
+1. `name`:
+ - 1-64 chars
+ - lowercase alphanumeric + hyphens
+ - no leading/trailing hyphen
+ - no consecutive hyphens
+ - must match parent directory name
+2. `description`:
+ - 1-1024 chars
+ - must describe what it does and when to use it
+
+Structure guidance:
+
+1. Keep main `SKILL.md` concise (recommended under 500 lines).
+2. Use progressive disclosure with `references/` and `scripts/`.
+3. Keep file references one level deep from `SKILL.md`.
+
+Validation gate:
+
+1. `skills-ref validate ./skills/sm-bigquery-analyst`
+
+## 6) skills.sh Publishing Convention
+
+Distribution model:
+
+1. Skills are hosted in GitHub repos.
+2. Install via CLI using one of:
+ - `npx skills add ` (collection/repo install)
+ - `npx skills add https://github.com// --skill ` (single-skill install)
+
+Leaderboard/listing convention:
+
+1. No manual listing flow required.
+2. Skills appear via anonymous install telemetry from `npx skills add`.
+
+Docs requirement for adoption:
+
+1. Publish copy/paste install commands on docs page.
+2. Include repo link and version/change notes.
+
+## 7) Verified SourceMedium System Constraints (Grounding)
+
+### 7.1 `reporting_queries` (dbt source of truth)
+
+1. Canonical dataset/model group definitions are in `dbt_project.yml`.
+2. Customer-facing rename map is in `mdw_schema_config.rename_column_map_all` (for example `smcid -> sm_store_id`).
+3. Customer-facing exclusions are in `mdw_schema_config.excluded_columns_all_tables`.
+4. Tenant metadata dictionary generation is tenant-table based.
+
+### 7.2 `uni` (runtime source of truth)
+
+1. Startup requires metadata from `{BIGQUERY_PROJECT_ID}.sm_metadata.dim_data_dictionary`.
+2. Table availability and schema context are metadata-gated.
+3. SQL flow is identify tables -> generate SQL -> normalize/cleanup -> dry-run -> execute.
+4. Docs context can be injected from Mintlify retrieval.
+
+### 7.3 `sourcemedium-docs` (canonical user docs routes)
+
+1. `/onboarding/analytics-tools/bigquery-essentials`
+2. `/data-activation/template-resources/sql-query-library`
+3. `/data-activation/data-tables/sm_transformed_v2/index`
+4. `/data-activation/data-tables/sm_metadata/dim_data_dictionary`
+5. `/help-center/core-concepts/data-definitions/is-order-sm-valid`
+6. `/onboarding/getting-started/how-to-manage-user-access`
+7. `/ai-analyst/agent-skills/bigquery-access-request-template`
+
+## 8) Skill UX Contract (Non-Negotiable)
+
+For analytical questions, always output:
+
+1. **Answer** (plain English).
+2. **SQL receipt** (copy/paste runnable BigQuery SQL).
+3. **Notes/assumptions** (time window, metric definition, grain, scope, timezone, attribution lens).
+4. **Verify command** (`bq query --use_legacy_sql=false ''`).
+
+If blocked by setup/access:
+
+1. State exact failing step.
+2. State exact permissions ask (project/dataset + role-level guidance).
+3. Include copy/paste request text the user can send to their internal admin.
+4. Never fabricate numbers.
+
+## 9) Query Guardrails (SourceMedium conventions)
+
+1. Fully qualify tables: `` `project.dataset.table` ``.
+2. Use `is_order_sm_valid = TRUE` for order analyses unless explicitly justified.
+3. Use `sm_store_id` (not `smcid`) in user-facing SQL.
+4. Use `SAFE_DIVIDE` for ratio metrics.
+5. Handle DATE/TIMESTAMP types explicitly.
+6. Avoid `LIKE`/`REGEXP` on low-cardinality categoricals; discover values first.
+7. Bound exploratory queries with `LIMIT` and time filters.
+
+## 10) Cross-Agent Packaging and Sync
+
+Canonical source:
+
+1. Dedicated/public skills repo (`skills/sm-bigquery-analyst`).
+
+Compatibility mirrors:
+
+1. Codex: `agents/openai.yaml` metadata in skill folder.
+2. Claude: mirrored copy under `.claude/skills/sm-bigquery-analyst/` in repos that need local invocation.
+
+Sync method (v1):
+
+1. Scripted one-way sync from canonical skill folder to mirror targets.
+2. Prevent manual drift by CI check (hash or diff check on `SKILL.md` and `references/`).
+
+## 11) Internal Insight Integration (Generated References)
+
+The user-facing `SKILL.md` stays concise. Internal depth lives in generated reference files:
+
+1. `references/generated/dbt-contract.md`
+ - Dataset defaults, model lists, rename map, exclusions.
+2. `references/generated/uni-execution-contract.md`
+ - Metadata prerequisites, table gating behavior, SQL validation lifecycle, docs-context behavior.
+
+Refresh mechanism:
+
+1. `scripts/refresh_references.sh` reads local sibling repos (`reporting_queries`, `uni`) and regenerates these files.
+
+## 12) Rollout Plan
+
+### Phase 1: Scaffold and compliance
+
+1. Create canonical skill folder.
+2. Implement spec-compliant frontmatter and structure.
+3. Add validation command in CI.
+
+### Phase 2: Content and grounding
+
+1. Draft SKILL workflow (setup -> verify -> analyze).
+2. Add generated internal references.
+3. Add docs map and troubleshooting references.
+
+### Phase 3: Publication
+
+1. Publish in GitHub skills repo.
+2. Add docs pages with install commands and examples.
+3. Validate install path via `npx skills add ...`.
+
+### Phase 4: Cross-agent QA
+
+Run prompt matrix in Codex and Claude:
+
+1. Missing CLI.
+2. Wrong project.
+3. Permission denied.
+4. Standard metric query.
+5. Ambiguous definition query.
+6. Suspicious data-quality query (must do discovery-first diagnostics).
+
+## 13) Acceptance Criteria (v1)
+
+1. One skill installs and runs via skills CLI from GitHub.
+2. Docs site contains human-facing skill page(s) with working install commands.
+3. `SKILL.md` passes Agent Skills validation requirements.
+4. Every analytical response includes SQL receipt + assumptions + verification command.
+5. SQL output follows SourceMedium naming/filter conventions.
+6. Internal grounding references are generated from both `reporting_queries` and `uni`.
+7. Dedicated docs article exists with minimum roles + admin request template.
+8. No fabricated outputs when setup/access fails.
+
+## 14) References
+
+Internal:
+
+1. `reporting_queries/dbt_project.yml`
+2. `reporting_queries/macros/distro/copy_data_mdw/dda_column_aliases.sql`
+3. `reporting_queries/macros/distro/mdw/utils/generate_tenant_data_dictionary.sql`
+4. `uni/src/platforms/slack/app.py`
+5. `uni/src/agent_core/async_utils.py`
+6. `uni/src/agent_core/agents/tools.py`
+7. `uni/src/integrations/mintlify.py`
+8. `sourcemedium-docs/onboarding/analytics-tools/bigquery-essentials.mdx`
+9. `sourcemedium-docs/data-activation/template-resources/sql-query-library.mdx`
+10. `sourcemedium-docs/data-activation/data-tables/sm_transformed_v2/index.mdx`
+11. `sourcemedium-docs/data-activation/data-tables/sm_metadata/dim_data_dictionary.mdx`
+12. `sourcemedium-docs/help-center/core-concepts/data-definitions/is-order-sm-valid.mdx`
+13. `sourcemedium-docs/onboarding/getting-started/how-to-manage-user-access.mdx`
+14. `sourcemedium-docs/ai-analyst/agent-skills/bigquery-access-request-template.mdx`
+
+External:
+
+1. https://agentskills.io/specification
+2. https://agentskills.io/integrate-skills
+3. https://agentskills.io/home
+4. https://skills.sh/docs/cli
+5. https://skills.sh/docs/faq
+6. https://cloud.google.com/bigquery/docs/access-control
+7. https://cloud.google.com/bigquery/docs/control-access-to-resources-iam
+8. https://cloud.google.com/iam/docs/granting-changing-revoking-access
diff --git a/tenants/README.md b/tenants/README.md
new file mode 100644
index 0000000..e1532e9
--- /dev/null
+++ b/tenants/README.md
@@ -0,0 +1,79 @@
+# Tenant-Specific Documentation
+
+This folder contains hidden documentation pages for individual tenants. These pages are **not** included in the public navigation and are only accessible via direct URL.
+
+## Structure
+
+```
+tenants/
+├── README.md # This file
+├── {tenant_id}/
+│ ├── index.mdx # Tenant overview page
+│ └── custom-objects.mdx # Custom objects inventory
+```
+
+## Access URLs
+
+Documentation is accessible at:
+- Overview: `https://docs.sourcemedium.com/tenants/{tenant_id}`
+- Custom Objects: `https://docs.sourcemedium.com/tenants/{tenant_id}/custom-objects`
+
+### Current Tenants
+
+| Tenant | Custom Objects | URL |
+|--------|---------------|-----|
+| avenuez | 5 | `/tenants/avenuez/custom-objects` |
+| catalinacrunch | 7 | `/tenants/catalinacrunch/custom-objects` |
+| catchco | 15 | `/tenants/catchco/custom-objects` |
+| cpap | 54 | `/tenants/cpap/custom-objects` |
+| elixhealing | 1 | `/tenants/elixhealing/custom-objects` |
+| fluencyfirm | 10 | `/tenants/fluencyfirm/custom-objects` |
+| guardianbikes | 32 | `/tenants/guardianbikes/custom-objects` |
+| idyl | 14 | `/tenants/idyl/custom-objects` |
+| irestore4 | 25 | `/tenants/irestore4/custom-objects` |
+| neurogum | 46 | `/tenants/neurogum/custom-objects` |
+| peoplebrandco | 8 | `/tenants/peoplebrandco/custom-objects` |
+| pillar3cx | 8 | `/tenants/pillar3cx/custom-objects` |
+| piquetea | 61 | `/tenants/piquetea/custom-objects` |
+| theperfectjean | 9 | `/tenants/theperfectjean/custom-objects` |
+| xcvi | 110 | `/tenants/xcvi/custom-objects` |
+| zbiotics | 284 | `/tenants/zbiotics/custom-objects` |
+
+## Data Source
+
+Documentation is generated from `sm-{tenant}.sm_metadata.dim_tenant_custom_objects` tables, which are populated by the `generate_dim_tenant_custom_objects` macro.
+
+### Regenerating Documentation
+
+To regenerate documentation for all tenants:
+
+```bash
+# 1. First, refresh the source data
+dbt run-operation generate_dim_tenant_custom_objects
+
+# 2. Then regenerate docs (use the Python script in /tmp or create a new one)
+python3 /tmp/generate_tenant_docs.py
+python3 /tmp/generate_tenant_index.py
+```
+
+### Adding a New Tenant
+
+1. Ensure the tenant has `dim_tenant_custom_objects` populated
+2. Add tenant to the generation scripts
+3. Run the generation scripts
+4. Commit the new MDX files
+
+## Security Model
+
+These pages use **security through obscurity**:
+- Not listed in public navigation (`docs.json`)
+- No authentication required
+- Accessible to anyone with the direct URL
+
+This is intentional - the data is metadata about table structures, not sensitive business data. For truly sensitive documentation, consider upgrading to Mintlify Pro for password protection.
+
+## Maintenance
+
+- **Automated updates**: Consider setting up a scheduled job to regenerate these docs weekly
+- **New tenants**: Add to generation scripts when onboarding
+- **Tenant offboarding**: Remove directory when tenant churns
diff --git a/tenants/REVIEW.md b/tenants/REVIEW.md
new file mode 100644
index 0000000..1b69e78
--- /dev/null
+++ b/tenants/REVIEW.md
@@ -0,0 +1,116 @@
+# Review Guide: Tenant-Specific Documentation
+
+## Overview
+
+This PR adds hidden tenant-specific documentation pages to the Mintlify docs site. Each tenant gets an inventory of their custom BigQuery objects (tables/views) with usage statistics.
+
+## What Changed
+
+1. **New macro**: `generate_dim_tenant_custom_objects` - Inventories active custom objects in a tenant's BigQuery project (queried at least once in the past 180 days)
+2. **New docs**: `mintlify/tenants/{tenant_id}/` - Hidden documentation pages for 16 tenants
+
+## How to Review
+
+### 1. Verify Data Accuracy
+
+Pick 2-3 tenants and spot-check the documentation against actual BigQuery data.
+
+**Important:** The table is partitioned by `snapshot_at` and may have multiple snapshots. Always filter to the latest snapshot to avoid double-counting:
+
+```sql
+-- Check custom objects for a tenant (latest snapshot only)
+WITH latest AS (
+ SELECT *,
+ ROW_NUMBER() OVER (PARTITION BY dataset_id, object_name ORDER BY snapshot_at DESC) as rn
+ FROM `sm-{tenant}.sm_metadata.dim_tenant_custom_objects`
+ WHERE classification IN ('tenant_dataset_custom', 'tenant_or_legacy_in_standard_dataset')
+)
+SELECT
+ dataset_id,
+ object_name,
+ object_type,
+ job_count_180d,
+ last_used_at
+FROM latest
+WHERE rn = 1
+ORDER BY CAST(job_count_180d AS INT64) DESC
+LIMIT 20;
+```
+
+Compare the output with the corresponding `custom-objects.mdx` file.
+
+### 2. Verify MDX Syntax
+
+Run Mintlify validation locally:
+
+```bash
+cd mintlify
+mintlify dev # Start local server, check for errors
+```
+
+**Note:** `mintlify dev` requires Node.js LTS (18 or 20). It may crash on Node 25+.
+
+Or just validate JSON:
+```bash
+python3 -m json.tool mintlify/docs.json
+```
+
+### 3. Check Hidden Page Behavior
+
+After deploying to a staging environment:
+1. Confirm pages are NOT visible in navigation
+2. Confirm pages ARE accessible via direct URL
+3. Check responsive layout on mobile
+
+### 4. Spot-Check Content Quality
+
+Review these files for formatting and content:
+
+**High-usage tenant (complex):**
+- `mintlify/tenants/zbiotics/custom-objects.mdx` - Has 100+ objects across many datasets
+
+**Medium-usage tenant:**
+- `mintlify/tenants/neurogum/custom-objects.mdx` - Has ~46 objects, manually enhanced
+
+**Low-usage tenant:**
+- `mintlify/tenants/catalinacrunch/custom-objects.mdx` - Has only 7 objects
+
+### 5. Verify Classification Logic
+
+The macro classifies objects into categories. Verify these make sense:
+
+```sql
+-- Check classification distribution for a tenant
+SELECT classification, COUNT(*) as cnt
+FROM `sm-neurogum.sm_metadata.dim_tenant_custom_objects`
+GROUP BY 1;
+```
+
+Expected classifications:
+- `tenant_dataset_custom` - Objects in tenant-created datasets (e.g., `customized_views`)
+- `tenant_or_legacy_in_standard_dataset` - Custom objects in SM datasets
+- `sm_owned_nondefault` - SM objects not in standard model set
+- `oob_v2` - Out-of-box v2 models (should NOT be in docs)
+
+## Key Files to Review
+
+| File | Purpose |
+|------|---------|
+| `macros/distro/mdw/utils/generate_dim_tenant_custom_objects.sql` | Source data generation |
+| `mintlify/tenants/README.md` | Documentation structure |
+| `mintlify/tenants/neurogum/custom-objects.mdx` | Example with manual enhancements |
+| `mintlify/tenants/zbiotics/custom-objects.mdx` | Complex multi-dataset example |
+
+## Questions for Reviewer
+
+1. Should we add more context to the index pages (e.g., tenant-specific notes)?
+2. Is the "low usage" warning threshold appropriate (objects with <100 queries in 180d)?
+3. Should we include DDL for all objects or just top objects?
+4. Do we need a way to exclude certain datasets from documentation (e.g., `dbt_*` developer datasets)?
+
+## Rollback Plan
+
+If issues arise after merge:
+1. Revert the `mintlify/tenants/` directory
+2. Pages will 404 (no navigation links to break)
+3. No impact on public documentation
diff --git a/tenants/avenuez.mdx b/tenants/avenuez.mdx
new file mode 100644
index 0000000..1133989
--- /dev/null
+++ b/tenants/avenuez.mdx
@@ -0,0 +1,52 @@
+---
+title: "AvenueZ"
+sidebarTitle: "AvenueZ"
+description: "Data documentation for AvenueZ"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-avenuez in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-avenuez`](https://console.cloud.google.com/bigquery?project=sm-avenuez) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m4!1m3!3m2!1ssm-avenuez!2ssm_transformed_v2) |
+| **Tenant ID** | `avenuez` |
diff --git a/tenants/avenuez/custom-objects.mdx b/tenants/avenuez/custom-objects.mdx
new file mode 100644
index 0000000..6d77ad4
--- /dev/null
+++ b/tenants/avenuez/custom-objects.mdx
@@ -0,0 +1,118 @@
+---
+title: "Avenue Z Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Avenue Z data warehouse"
+icon: "database"
+---
+
+[← Back to Avenue Z](/tenants/avenuez) | [Open sm-avenuez in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-avenuez)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Avenue Z, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:45 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m4!1m3!3m2!1ssm-avenuez!2scustomized_views) | 5 | 46,934 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 16,131
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m5!1m4!4m3!1ssm-avenuez!2scustomized_views!3srpt_executive_summary_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-avenuez.customized_views.rpt_executive_summary_daily_customized` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13,420
+
+Custom data Key columns: `date, sm_store_id, sm_channel, sm_sub_channel, total_repeat_customer_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m5!1m4!4m3!1ssm-avenuez!2scustomized_views!3savez_exec_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-avenuez.customized_views.avez_exec_custom` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 10,726
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m5!1m4!4m3!1ssm-avenuez!2scustomized_views!3srpt_ad_performance_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-avenuez.customized_views.rpt_ad_performance_daily_customized` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,336
+
+Order-level data Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m5!1m4!4m3!1ssm-avenuez!2scustomized_views!3savez_orders_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-avenuez.customized_views.avez_orders_custom` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,321
+
+Marketing/advertising data Key columns: `sm_store_id, source_system, sub_channel, date, ad_clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m5!1m4!4m3!1ssm-avenuez!2scustomized_views!3savez_marketing_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-avenuez.customized_views.avez_marketing_custom` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-avenuez` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`avenuez`](https://console.cloud.google.com/bigquery?project=sm-avenuez&ws=!1m4!1m3!3m2!1ssm-avenuez!2savenuez)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/catalinacrunch.mdx b/tenants/catalinacrunch.mdx
new file mode 100644
index 0000000..436e408
--- /dev/null
+++ b/tenants/catalinacrunch.mdx
@@ -0,0 +1,52 @@
+---
+title: "Catalina Crunch"
+sidebarTitle: "Catalina Crunch"
+description: "Data documentation for Catalina Crunch"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-catalinacrunch in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-catalinacrunch`](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m4!1m3!3m2!1ssm-catalinacrunch!2ssm_transformed_v2) |
+| **Tenant ID** | `catalinacrunch` |
diff --git a/tenants/catalinacrunch/custom-objects.mdx b/tenants/catalinacrunch/custom-objects.mdx
new file mode 100644
index 0000000..bac9fda
--- /dev/null
+++ b/tenants/catalinacrunch/custom-objects.mdx
@@ -0,0 +1,144 @@
+---
+title: "Catalina Crunch Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Catalina Crunch data warehouse"
+icon: "database"
+---
+
+[← Back to Catalina Crunch](/tenants/catalinacrunch) | [Open sm-catalinacrunch in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Catalina Crunch, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:46 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m4!1m3!3m2!1ssm-catalinacrunch!2scustomized_views) | 7 | 2,973 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 996
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3ssales_by_flavor)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.sales_by_flavor` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 996
+
+Product/SKU-level data Key columns: `variant_sku, product_type, sub_category, flavor, category`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3ssku_categorization)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.sku_categorization` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 471
+
+Custom data Key columns: `start_date, end_date, gross_margin, operating_expenses, shipping_cost_per_order`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3scogs_opex_by_month)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.cogs_opex_by_month` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 471
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3sprofit_and_loss)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.profit_and_loss` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13
+
+Custom data Key columns: `zip_code, dma_code, dma_nielsen, dma_meta`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3sdma_zip_codes)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.dma_zip_codes` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 13
+
+Custom data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3sdma_zip_codes_sm)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.dma_zip_codes_sm` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13
+
+Custom data Key columns: `spins_market, sm_channel, time_period_end_date, product_level, category`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m5!1m4!4m3!1ssm-catalinacrunch!2scustomized_views!3sspins_all_cat_markets_mulo_trended_csv)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catalinacrunch.customized_views.spins_all_cat_markets_mulo_trended_csv` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-catalinacrunch` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`catalinacrunch`](https://console.cloud.google.com/bigquery?project=sm-catalinacrunch&ws=!1m4!1m3!3m2!1ssm-catalinacrunch!2scatalinacrunch)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/catchco.mdx b/tenants/catchco.mdx
new file mode 100644
index 0000000..62b4c08
--- /dev/null
+++ b/tenants/catchco.mdx
@@ -0,0 +1,52 @@
+---
+title: "Catch Co"
+sidebarTitle: "Catch Co"
+description: "Data documentation for Catch Co"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-catchco in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-catchco`](https://console.cloud.google.com/bigquery?project=sm-catchco) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m4!1m3!3m2!1ssm-catchco!2ssm_transformed_v2) |
+| **Tenant ID** | `catchco` |
diff --git a/tenants/catchco/custom-objects.mdx b/tenants/catchco/custom-objects.mdx
new file mode 100644
index 0000000..b85075f
--- /dev/null
+++ b/tenants/catchco/custom-objects.mdx
@@ -0,0 +1,256 @@
+---
+title: "Catch Co Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Catch Co data warehouse"
+icon: "database"
+---
+
+[← Back to Catch Co](/tenants/catchco) | [Open sm-catchco in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-catchco)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Catch Co, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:48 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m4!1m3!3m2!1ssm-catchco!2scustomized_views) | 13 | 28,085 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m4!1m3!3m2!1ssm-catchco!2ssm_sources) | 1 | 1,102 |
+| [`sm_utils`](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m4!1m3!3m2!1ssm-catchco!2ssm_utils) | 1 | 243 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 20,889
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sobt_orders_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.obt_orders_customized` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,882
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3srpt_executive_summary_daily_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.rpt_executive_summary_daily_custom` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,092
+
+Custom data Key columns: `channel, date, metric, daily_value`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3scatch_co_target_array)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.catch_co_target_array` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 999
+
+Denormalized "One Big Table" view Key columns: `order_date, sm_channel, sm_store_id, new_subscription_orders, new_subscription_net_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sobt_summary_with_forecasting)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.obt_summary_with_forecasting` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 852
+
+Aggregated summary Key columns: `order_date, order_date_last_year, sm_channel, sm_store_id, new_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3srpt_yoy_executive_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.rpt_yoy_executive_summary` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 656
+
+Weekly aggregation Key columns: `date, week_start_date, year_week, week_number, month_start_date`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sweekly_business_review)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.weekly_business_review` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 498
+
+Denormalized "One Big Table" view Key columns: `sm_channel, date, forecasted_total_gross_revenue, forecasted_total_net_revenue, forecasted_total_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sobt_forecasting_amortized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.obt_forecasting_amortized` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 453
+
+Aggregated summary Key columns: `date, sm_channel, source_system, sm_store_id, ad_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3srpt_exec_ad_performance)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.rpt_exec_ad_performance` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 243
+
+Custom data Key columns: `channel, date_start, date_end, total_gross_revenue, total_net_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sforecasting_sheet_src)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.forecasting_sheet_src` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 225
+
+Order-level data Key columns: `order_date, sm_channel, prepaid_count, gift_redemption_count, subscription_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sorders_logic_aggregation)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.orders_logic_aggregation` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 154
+
+Aggregated summary Key columns: `order_date, order_date_last_year, sm_channel, sm_store_id, new_subscription_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3srpt_yoy_non_recurringong_product_comparison)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.rpt_yoy_non_recurringong_product_comparison` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 137
+
+Aggregated summary Key columns: `date, sm_channel, sm_store_id, new_orders, new_net_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3srpt_contribution_margin_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.rpt_contribution_margin_summary` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5
+
+Denormalized "One Big Table" view Key columns: `order_date, prepaid_count, gift_redemption_count, subscription_count, gift_order_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2scustomized_views!3sobt_orders_aggregated)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.customized_views.obt_orders_aggregated` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,102
+
+Custom data Key columns: `_airbyte_raw_id, _airbyte_extracted_at, _airbyte_generation_id, email`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2ssm_sources!3smtb_fairing_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.sm_sources.mtb_fairing_responses` LIMIT 10;
+```
+
+
+
+### sm_utils
+
+
+**Type:** EXTERNAL | **Queries (180d):** 243
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m5!1m4!4m3!1ssm-catchco!2ssm_utils!3sforecasting_sheet_ext)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-catchco.sm_utils.forecasting_sheet_ext` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-catchco` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`catchco`](https://console.cloud.google.com/bigquery?project=sm-catchco&ws=!1m4!1m3!3m2!1ssm-catchco!2scatchco)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/cpap.mdx b/tenants/cpap.mdx
new file mode 100644
index 0000000..c2c97c1
--- /dev/null
+++ b/tenants/cpap.mdx
@@ -0,0 +1,52 @@
+---
+title: "CPAP"
+sidebarTitle: "CPAP"
+description: "Data documentation for CPAP"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-cpap in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-cpap`](https://console.cloud.google.com/bigquery?project=sm-cpap) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2ssm_transformed_v2) |
+| **Tenant ID** | `cpap` |
diff --git a/tenants/cpap/custom-objects.mdx b/tenants/cpap/custom-objects.mdx
new file mode 100644
index 0000000..190aa95
--- /dev/null
+++ b/tenants/cpap/custom-objects.mdx
@@ -0,0 +1,783 @@
+---
+title: "CPAP Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the CPAP data warehouse"
+icon: "database"
+---
+
+[← Back to CPAP](/tenants/cpap) | [Open sm-cpap in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-cpap)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for CPAP, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:46 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`machine_v_non_pipeline`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2smachine_v_non_pipeline) | 8 | 511,419 |
+| [`cpap_sources`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scpap_sources) | 9 | 147,143 |
+| [`cpap_transformed`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scpap_transformed) | 9 | 81,561 |
+| [`cpap_views`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scpap_views) | 21 | 34,024 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2ssm_sources) | 2 | 4,402 |
+| [`cpap_date_in_views`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scpap_date_in_views) | 3 | 1,002 |
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scustomized_views) | 1 | 286 |
+| [`QA`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2sQA) | 1 | 11 |
+
+---
+
+## Objects by Dataset
+
+### machine_v_non_pipeline
+
+
+**Type:** BASE TABLE | **Queries (180d):** 130,049
+
+Order-level data Key columns: `sm_order_key, order_id, order_number, sm_store_id, sm_customer_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sorders_agg_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.orders_agg_custom` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 107,758
+
+Custom data Key columns: `sm_channel, date, first_time_orders, repeat_orders, orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sexecutive_summary_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.executive_summary_custom` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 64,850
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sobt_order_lines_custom)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.obt_order_lines_custom` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 62,880
+
+Order-level data Key columns: `sm_channel, date, first_time_orders, repeat_orders, orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sdaily_orders_agg)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.daily_orders_agg` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 62,867
+
+Marketing/advertising data Key columns: `date, ad_spend, ad_clicks, ad_impressions, sm_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sdaily_marketing_agg)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.daily_marketing_agg` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 46,202
+
+Custom data Key columns: `refunded_date, sm_channel, total_order_line_refund_quantity, total_shipping_refunds, total_shipping_tax_refunds`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3srefund_actions_processed)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.refund_actions_processed` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 36,722
+
+Custom data Key columns: `date, channel, machine_order_flag, order_count, revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3sdaily_machine_v_agg)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.daily_machine_v_agg` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 91
+
+Custom data Key columns: `order_line_id, product_cost, record_created_at, date_out`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2smachine_v_non_pipeline!3smc_lineitem_cost_deduped)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.machine_v_non_pipeline.mc_lineitem_cost_deduped` LIMIT 10;
+```
+
+
+
+### cpap_sources
+
+
+**Type:** BASE TABLE | **Queries (180d):** 37,261
+
+Custom data Key columns: `shopify_order_id, shopify_order_name, order_line_id, sku, madcow_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3smc_lineitem_cost)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.mc_lineitem_cost` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 35,057
+
+Custom data Key columns: `date, fiscal_year, fiscal_quarter, fiscal_month, fiscal_week`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3smc_time_dimension)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.mc_time_dimension` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 31,445
+
+Custom data Key columns: `source, source_category`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3sga_source_category_map)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.ga_source_category_map` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 16,179
+
+Custom data Key columns: `sm_store_id, source_system, sm_channel, date, ad_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3smc_ttd_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.mc_ttd_data` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13,272
+
+Order-level data Key columns: `shopify_order_id, shopify_order_name, madcow_order_number, magento_increment_id, magento_order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3smc_order_cost)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.mc_order_cost` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7,343
+
+Marketing/advertising data Key columns: `Date, Sessions, Orders, Revenue, RevenueGrandTotal`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3sDataformGADailyCompanyMetrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.DataformGADailyCompanyMetrics` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 6,161
+
+Custom data Key columns: `date, target_type, target_channel, target_value`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3scpap_targets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.cpap_targets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 415
+
+Custom data Key columns: `sku, quantity_on_hand, log_date, record_created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3smc_quantity_on_hand)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.mc_quantity_on_hand` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 10
+
+Product/SKU-level data Key columns: `_portable_extracted, admin_graphql_api_id, body_html, created_at, handle`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_sources!3sshopify_products_8589937895)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_sources.shopify_products_8589937895` LIMIT 10;
+```
+
+
+
+### cpap_transformed
+
+
+**Type:** BASE TABLE | **Queries (180d):** 41,369
+
+Order-level data Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_obt_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_obt_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 12,821
+
+Daily aggregation
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_outbound_message_performance_sm_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_outbound_message_performance_sm_daily` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 10,027
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_rpt_ad_performance_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_rpt_ad_performance_daily` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8,412
+
+Daily aggregation Key columns: `date, day_number, fiscal_week, fiscal_month, fiscal_quarter`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_rpt_financial_channel_summary_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_rpt_financial_channel_summary_daily` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7,523
+
+Aggregated summary Key columns: `Date, fiscal_year, fiscal_month, day_number, Sessions`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3srpt_shopify_adjusted_session_start_method__by_day)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.rpt_shopify_adjusted_session_start_method__by_day` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,113
+
+Order-level data Key columns: `order_id, order_status, payment_status, fulfillment_status, return_status`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_order_status)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_order_status` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 150
+
+Product/SKU-level data Key columns: `sm_channel, order_processed_date, anchor_sku, anchor_product_title, anchor_division`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_rpt_sku_attachment_rate_daily_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_rpt_sku_attachment_rate_daily_summary` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 136
+
+Aggregated summary Key columns: `sm_channel, order_processed_date, anchor_division, attachment_division, anchor_order_line_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_rpt_division_attachment_rate_daily_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_rpt_division_attachment_rate_daily_summary` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 10
+
+Daily aggregation
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_transformed!3scpap_parts_division_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_transformed.cpap_parts_division_daily` LIMIT 10;
+```
+
+
+
+### cpap_views
+
+
+**Type:** VIEW | **Queries (180d):** 14,469
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_ad_performance_daily_metrics_unioned)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_ad_performance_daily_metrics_unioned` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 7,720
+
+Weekly aggregation
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_push_report_weekly)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_push_report_weekly` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 5,979
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_channel_data_live)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_channel_data_live` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,468
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3stheo_obt_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.theo_obt_orders` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,169
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sRx_Renewal_Without_Docusign)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.Rx_Renewal_Without_Docusign` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 800
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sparts_category_live)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.parts_category_live` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 734
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scustomer_summary_live)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.customer_summary_live` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 620
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_parts_quantity_channel_live)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_parts_quantity_channel_live` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 415
+
+Custom data Key columns: `AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sparts_details_live)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.parts_details_live` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 371
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_ad_performance_daily_with_targets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_ad_performance_daily_with_targets` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 77
+
+Custom data Key columns: `BETWEEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_rx_renewal_daily_envelope_lifecycle)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_rx_renewal_daily_envelope_lifecycle` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 61
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sdate_in_aov_cohorts)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.date_in_aov_cohorts` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 37
+
+Daily aggregation
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_session_engagement_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_session_engagement_daily` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 36
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sdate_in_orders_with_customer_cohorts)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.date_in_orders_with_customer_cohorts` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 21
+
+Custom data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3shaus_kpi_date_region)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.haus_kpi_date_region` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 14
+
+Monthly aggregation Key columns: `AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_monthly_revenue)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_monthly_revenue` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 12
+
+Monthly aggregation Key columns: `select`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_monthly_refund)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_monthly_refund` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 11
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_rx_renewal_voided_stage_abandoned)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_rx_renewal_voided_stage_abandoned` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4
+
+Metrics definitions
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3scpap_rpt_session_engagement_daily_metrics_unioned)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.cpap_rpt_session_engagement_daily_metrics_unioned` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3sactive_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.active_customers` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_views!3s2021_customer_cohort_ltv)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_views.2021_customer_cohort_ltv` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,330
+
+Custom data Key columns: `_sdc_shop_id, key, owner_id, _sdc_table_version`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2ssm_sources!3ssrc_shopify__metafields)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.sm_sources.src_shopify__metafields` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 72
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2ssm_sources!3scpap_rpt_ad_performance_daily_fiscal_year_test)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.sm_sources.cpap_rpt_ad_performance_daily_fiscal_year_test` LIMIT 10;
+```
+
+
+
+### cpap_date_in_views
+
+
+**Type:** VIEW | **Queries (180d):** 360
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_date_in_views!3srpt_shopify_sales_summary_by_channel_day)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_date_in_views.rpt_shopify_sales_summary_by_channel_day` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 360
+
+Aggregated summary Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_date_in_views!3srpt_shopify_sales_summary_by_customer_day)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_date_in_views.rpt_shopify_sales_summary_by_customer_day` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 282
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scpap_date_in_views!3srpt_shopify_sales_summary_by_category_day)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.cpap_date_in_views.rpt_shopify_sales_summary_by_category_day` LIMIT 10;
+```
+
+
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 286
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2scustomized_views!3sobt_orders_filtered_gross_profit)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.customized_views.obt_orders_filtered_gross_profit` LIMIT 10;
+```
+
+
+
+### QA
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `mc_order_number, mg_order_number, mc_date_out, mc_channel, mc_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m5!1m4!4m3!1ssm-cpap!2sQA!3smc_QA_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-cpap.QA.mc_QA_data` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-cpap` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`cpap`](https://console.cloud.google.com/bigquery?project=sm-cpap&ws=!1m4!1m3!3m2!1ssm-cpap!2scpap)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/elixhealing.mdx b/tenants/elixhealing.mdx
new file mode 100644
index 0000000..0201ee2
--- /dev/null
+++ b/tenants/elixhealing.mdx
@@ -0,0 +1,52 @@
+---
+title: "Elix Healing"
+sidebarTitle: "Elix Healing"
+description: "Data documentation for Elix Healing"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-elixhealing in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-elixhealing`](https://console.cloud.google.com/bigquery?project=sm-elixhealing) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-elixhealing&ws=!1m4!1m3!3m2!1ssm-elixhealing!2ssm_transformed_v2) |
+| **Tenant ID** | `elixhealing` |
diff --git a/tenants/elixhealing/custom-objects.mdx b/tenants/elixhealing/custom-objects.mdx
new file mode 100644
index 0000000..b45f333
--- /dev/null
+++ b/tenants/elixhealing/custom-objects.mdx
@@ -0,0 +1,66 @@
+---
+title: "Elix Healing Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Elix Healing data warehouse"
+icon: "database"
+---
+
+[← Back to Elix Healing](/tenants/elixhealing) | [Open sm-elixhealing in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-elixhealing)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Elix Healing, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-elixhealing&ws=!1m4!1m3!3m2!1ssm-elixhealing!2scustomized_views) | 1 | 31 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 31
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-elixhealing&ws=!1m5!1m4!4m3!1ssm-elixhealing!2scustomized_views!3srpt_customers_1st_last_with_sku_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-elixhealing.customized_views.rpt_customers_1st_last_with_sku_history` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-elixhealing` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`elixhealing`](https://console.cloud.google.com/bigquery?project=sm-elixhealing&ws=!1m4!1m3!3m2!1ssm-elixhealing!2selixhealing)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/fluencyfirm.mdx b/tenants/fluencyfirm.mdx
new file mode 100644
index 0000000..4cd6ff6
--- /dev/null
+++ b/tenants/fluencyfirm.mdx
@@ -0,0 +1,52 @@
+---
+title: "FluencyFirm"
+sidebarTitle: "FluencyFirm"
+description: "Data documentation for FluencyFirm"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-fluencyfirm in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-fluencyfirm`](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m4!1m3!3m2!1ssm-fluencyfirm!2ssm_transformed_v2) |
+| **Tenant ID** | `fluencyfirm` |
diff --git a/tenants/fluencyfirm/custom-objects.mdx b/tenants/fluencyfirm/custom-objects.mdx
new file mode 100644
index 0000000..9bb07a7
--- /dev/null
+++ b/tenants/fluencyfirm/custom-objects.mdx
@@ -0,0 +1,183 @@
+---
+title: "FluencyFirm Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the FluencyFirm data warehouse"
+icon: "database"
+---
+
+[← Back to FluencyFirm](/tenants/fluencyfirm) | [Open sm-fluencyfirm in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for FluencyFirm, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:45 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m4!1m3!3m2!1ssm-fluencyfirm!2scustomized_views) | 10 | 383,665 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 172,835
+
+Aggregated summary Key columns: `sm_store_id, sm_channel, sm_sub_channel, date, sun_sat_week_start`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3srpt_executive_summary_converted)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.rpt_executive_summary_converted` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 103,625
+
+Aggregated summary Key columns: `sm_store_id, sun_sat_week_start, sun_sat_week_end, ad_platform_reported_conversions, ad_platform_reported_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3srpt_ad_performance_daily_corrected)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.rpt_ad_performance_daily_corrected` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 42,308
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3sobt_order_lines_converted)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.obt_order_lines_converted` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 40,895
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3sobt_orders_converted)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.obt_orders_converted` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 15,496
+
+Custom data Key columns: `date, iso_week_num, year_ref, spend, last_week_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3scustom_blended_kpi_view)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.custom_blended_kpi_view` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,275
+
+Custom data Key columns: `date, iso_week_num, year_ref, spend, last_week_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3scustom_blended_kpi_view_refunds_changed)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.custom_blended_kpi_view_refunds_changed` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,875
+
+Aggregated summary Key columns: `customer_id, customer_email, customer_email_hashed, customer_first_order_id, customer_last_order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3srpt_customers_first_and_last_order_summary_converted)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.rpt_customers_first_and_last_order_summary_converted` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 2,144
+
+Custom data Key columns: `Store_Name, Store_ID, Configuration_Sheet_Link`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3sff_config_sheet_links)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.ff_config_sheet_links` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 145
+
+Order-level data Key columns: `sm_store_id, order_id, customer_id, order_index_adjusted, order_index`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3sorder_indexes_corrected)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.order_indexes_corrected` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 67
+
+Denormalized "One Big Table" view Key columns: `Store_Name, sm_store_id, Configuration_Sheet_Link`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m5!1m4!4m3!1ssm-fluencyfirm!2scustomized_views!3sobt_config_sheet_links)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-fluencyfirm.customized_views.obt_config_sheet_links` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-fluencyfirm` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`fluencyfirm`](https://console.cloud.google.com/bigquery?project=sm-fluencyfirm&ws=!1m4!1m3!3m2!1ssm-fluencyfirm!2sfluencyfirm)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/guardianbikes.mdx b/tenants/guardianbikes.mdx
new file mode 100644
index 0000000..1e5d8a2
--- /dev/null
+++ b/tenants/guardianbikes.mdx
@@ -0,0 +1,52 @@
+---
+title: "Guardian Bikes"
+sidebarTitle: "Guardian Bikes"
+description: "Data documentation for Guardian Bikes"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-guardianbikes in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-guardianbikes`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssm_transformed_v2) |
+| **Tenant ID** | `guardianbikes` |
diff --git a/tenants/guardianbikes/custom-objects.mdx b/tenants/guardianbikes/custom-objects.mdx
new file mode 100644
index 0000000..bb0d46c
--- /dev/null
+++ b/tenants/guardianbikes/custom-objects.mdx
@@ -0,0 +1,489 @@
+---
+title: "Guardian Bikes Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Guardian Bikes data warehouse"
+icon: "database"
+---
+
+[← Back to Guardian Bikes](/tenants/guardianbikes) | [Open sm-guardianbikes in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Guardian Bikes, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`sp_snowplow_scratch`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssp_snowplow_scratch) | 13 | 36,678 |
+| [`sp_snowplow_derived`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssp_snowplow_derived) | 8 | 29,263 |
+| [`sp_snowplow_snowplow_manifest`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest) | 7 | 24,813 |
+| [`sp_snowplow`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssp_snowplow) | 2 | 6,486 |
+| [`sm_custom_models`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2ssm_custom_models) | 1 | 1,080 |
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2scustomized_views) | 1 | 6 |
+
+---
+
+## Objects by Dataset
+
+### sp_snowplow_scratch
+
+
+**Type:** BASE TABLE | **Queries (180d):** 9,710
+
+Custom data Key columns: `lower_limit, upper_limit`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_base_new_event_limits)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_base_new_event_limits` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 6,474
+
+Custom data Key columns: `session_identifier, app_id, platform, etl_tstamp, collector_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_events_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_events_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,316
+
+Custom data Key columns: `session_identifier, user_identifier, start_tstamp, end_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_base_sessions_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_base_sessions_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,234
+
+Custom data Key columns: `first_event_name, last_event_name, session_identifier, user_id, user_identifier`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_users_sessions_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_users_sessions_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,158
+
+Custom data Key columns: `session_identifier, app_id, platform, etl_tstamp, collector_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_base_events_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_base_events_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,158
+
+Custom data Key columns: `cv_id, event_id, session_identifier, user_identifier, user_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_conversions_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_conversions_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,156
+
+Custom data Key columns: `user_identifier, start_tstamp, end_tstamp, first_session_identifier, last_session_identifier`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_users_aggs)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_users_aggs` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `view_id, session_identifier, end_tstamp, engaged_time_in_s, absolute_time_in_s`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_pv_engaged_time)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_pv_engaged_time` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `view_id, event_name, event_id, session_identifier, view_in_session_index`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_views_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_views_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `first_event_name, last_event_name, session_identifier, user_id, user_identifier`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_sessions_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_sessions_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `view_id, session_identifier, doc_width, doc_height, br_viewwidth`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_pv_scroll_depth)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_pv_scroll_depth` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,078
+
+Custom data Key columns: `user_id, user_identifier, network_userid, stitched_user_id, start_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_users_this_run)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_users_this_run` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,078
+
+Custom data Key columns: `user_identifier, last_platform, last_os_type, last_os_version, last_screen_resolution`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_scratch!3ssnowplow_unified_users_lasts)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_scratch.snowplow_unified_users_lasts` LIMIT 10;
+```
+
+
+
+### sp_snowplow_derived
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5,393
+
+Custom data Key columns: `user_identifier, user_id, end_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_unified_user_mapping)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_unified_user_mapping` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5,392
+
+Custom data Key columns: `cv_id, event_id, customer_id, cv_tstamp, cv_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_attribution_paths_to_conversion)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_attribution_paths_to_conversion` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,322
+
+Custom data Key columns: `cv_id, event_id, session_identifier, user_identifier, user_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_unified_conversions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_unified_conversions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,330
+
+Custom data Key columns: `first_event_name, last_event_name, session_identifier, user_id, user_identifier`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_unified_sessions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_unified_sessions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,260
+
+Custom data Key columns: `view_id, event_name, event_id, session_identifier, view_in_session_index`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_unified_views)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_unified_views` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,235
+
+Marketing/advertising data Key columns: `composite_key, cv_id, event_id, customer_id, cv_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_attribution_campaign_attributions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_attribution_campaign_attributions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,175
+
+Custom data Key columns: `composite_key, cv_id, event_id, customer_id, cv_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_attribution_channel_attributions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_attribution_channel_attributions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,156
+
+Custom data Key columns: `user_id, user_identifier, network_userid, stitched_user_id, start_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_derived!3ssnowplow_unified_users)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_derived.snowplow_unified_users` LIMIT 10;
+```
+
+
+
+### sp_snowplow_snowplow_manifest
+
+
+**Type:** BASE TABLE | **Queries (180d):** 9,710
+
+Custom data Key columns: `model, last_success`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_incremental_manifest)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_incremental_manifest` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,316
+
+Custom data Key columns: `session_identifier`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_base_quarantined_sessions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_base_quarantined_sessions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,237
+
+Custom data Key columns: `session_identifier, user_identifier, start_tstamp, end_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_base_sessions_lifecycle_manifest)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_base_sessions_lifecycle_manifest` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,234
+
+Custom data Key columns: `model, processed_at, conversion_hosts, path_transforms, path_lookback_steps`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_attribution_incremental_manifest)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_attribution_incremental_manifest` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,158
+
+Custom data Key columns: `source, source_category`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_dim_ga4_source_categories)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_dim_ga4_source_categories` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `name, alpha_2, alpha_3, country_code, iso_3166_2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_dim_geo_country_mapping)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_dim_geo_country_mapping` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,079
+
+Custom data Key columns: `lang_tag, name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow_snowplow_manifest!3ssnowplow_unified_dim_rfc_5646_language_mapping)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow_snowplow_manifest.snowplow_unified_dim_rfc_5646_language_mapping` LIMIT 10;
+```
+
+
+
+### sp_snowplow
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5,400
+
+Custom data Key columns: `app_id, platform, etl_tstamp, collector_tstamp, dvce_created_tstamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow!3sevents)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow.events` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,086
+
+Custom data Key columns: `order_id, order_name, domain_userid, collector_tstamp, event_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssp_snowplow!3ssession_events_for_transactions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sp_snowplow.session_events_for_transactions` LIMIT 10;
+```
+
+
+
+### sm_custom_models
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,080
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, source_system, event_id, event_user_id, event_user_session_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2ssm_custom_models!3sobt_funnel_event_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.sm_custom_models.obt_funnel_event_history` LIMIT 10;
+```
+
+
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 6
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m5!1m4!4m3!1ssm-guardianbikes!2scustomized_views!3sorder_line_refunds_processed)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-guardianbikes.customized_views.order_line_refunds_processed` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-guardianbikes` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`guardianbikes`](https://console.cloud.google.com/bigquery?project=sm-guardianbikes&ws=!1m4!1m3!3m2!1ssm-guardianbikes!2sguardianbikes)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/idyl.mdx b/tenants/idyl.mdx
new file mode 100644
index 0000000..5322847
--- /dev/null
+++ b/tenants/idyl.mdx
@@ -0,0 +1,52 @@
+---
+title: "Idyl"
+sidebarTitle: "Idyl"
+description: "Data documentation for Idyl"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-idyl in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-idyl`](https://console.cloud.google.com/bigquery?project=sm-idyl) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m4!1m3!3m2!1ssm-idyl!2ssm_transformed_v2) |
+| **Tenant ID** | `idyl` |
diff --git a/tenants/idyl/custom-objects.mdx b/tenants/idyl/custom-objects.mdx
new file mode 100644
index 0000000..606a9f3
--- /dev/null
+++ b/tenants/idyl/custom-objects.mdx
@@ -0,0 +1,243 @@
+---
+title: "Idyl Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Idyl data warehouse"
+icon: "database"
+---
+
+[← Back to Idyl](/tenants/idyl) | [Open sm-idyl in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-idyl)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Idyl, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:49 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`sm_consulting`](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m4!1m3!3m2!1ssm-idyl!2ssm_consulting) | 1 | 762 |
+| [`tydo_historic_pre_2026`](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m4!1m3!3m2!1ssm-idyl!2stydo_historic_pre_2026) | 7 | 62 |
+| [`src_lucky_orange`](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m4!1m3!3m2!1ssm-idyl!2ssrc_lucky_orange) | 6 | 56 |
+
+---
+
+## Objects by Dataset
+
+### sm_consulting
+
+
+**Type:** BASE TABLE | **Queries (180d):** 762
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, source_system, sm_touch_id, event_user_id, sm_event_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssm_consulting!3sobt_purchase_journeys_with_mta_models_lo_only_jan_21_2026)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.sm_consulting.obt_purchase_journeys_with_mta_models_lo_only_jan_21_2026` LIMIT 10;
+```
+
+
+
+### tydo_historic_pre_2026
+
+
+**Type:** BASE TABLE | **Queries (180d):** 32
+
+Custom data Key columns: `source_project, source_dataset, source_table, dest_project, dest_dataset`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3s_table_catalog)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026._table_catalog` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8
+
+Order-level data Key columns: `_fivetran_deleted, app_id, billing_address_address_1`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sshopify__idyl__order)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.shopify__idyl__order` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5
+
+Marketing/advertising data Key columns: `_fivetran_id, ad_id, date, account_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sfacebook_ads__idyl__ad_level_reporting)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.facebook_ads__idyl__ad_level_reporting` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 5
+
+Order-level data Key columns: `_airbyte_ab_id, _airbyte_emitted_at, name, note`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sidyl__shopify_order)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.idyl__shopify_order` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4
+
+Marketing/advertising data Key columns: `_fivetran_id, customer_id, date, active_view_cpm`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sgoogle_ads__idyl__campaign_hourly_stats)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.google_ads__idyl__campaign_hourly_stats` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4
+
+Custom data Key columns: `_fivetran_id, date, profile, landing_page_path`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sgoogle_analytics_idyl__landing_page_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.google_analytics_idyl__landing_page_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4
+
+Order-level data Key columns: `_airbyte_ab_id, _airbyte_emitted_at, sku, name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2stydo_historic_pre_2026!3sidyl__shopify_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.tydo_historic_pre_2026.idyl__shopify_order_line` LIMIT 10;
+```
+
+
+
+### src_lucky_orange
+
+
+**Type:** BASE TABLE | **Queries (180d):** 14
+
+Custom data Key columns: `_source_system_relation, sm_event_key, sm_store_id, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3shistorical_sessions_pre_2026_backfilled_sample)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.historical_sessions_pre_2026_backfilled_sample` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Staging data Key columns: `sm_store_id, sm_touch_id, source_system, event_id, event_user_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3sstg_purchase_journey_touches)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.stg_purchase_journey_touches` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8
+
+Custom data Key columns: `_source_system_relation, sm_event_key, sm_store_id, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3shistorical_sessions_pre_2026)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.historical_sessions_pre_2026` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8
+
+Intermediate transformation Key columns: `sm_store_id, sm_touch_id, source_system, event_id, event_user_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3sint_purchase_journey_valid_touches)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.int_purchase_journey_valid_touches` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8
+
+Custom data Key columns: `sm_touch_id, smcid, source_system, event_id, event_user_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3spurchase_journey_touches_test)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.purchase_journey_touches_test` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7
+
+Intermediate transformation Key columns: `sm_store_id, source_system, event_identifier, purchase_order_id, first_valid_sm_touch_id_landing_page`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m5!1m4!4m3!1ssm-idyl!2ssrc_lucky_orange!3sint_purchase_journey_purchases)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-idyl.src_lucky_orange.int_purchase_journey_purchases` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-idyl` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`idyl`](https://console.cloud.google.com/bigquery?project=sm-idyl&ws=!1m4!1m3!3m2!1ssm-idyl!2sidyl)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/irestore4.mdx b/tenants/irestore4.mdx
new file mode 100644
index 0000000..15ecc7d
--- /dev/null
+++ b/tenants/irestore4.mdx
@@ -0,0 +1,52 @@
+---
+title: "iRestore"
+sidebarTitle: "iRestore"
+description: "Data documentation for iRestore"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-irestore4 in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-irestore4`](https://console.cloud.google.com/bigquery?project=sm-irestore4) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2ssm_transformed_v2) |
+| **Tenant ID** | `irestore4` |
diff --git a/tenants/irestore4/custom-objects.mdx b/tenants/irestore4/custom-objects.mdx
new file mode 100644
index 0000000..f672fe2
--- /dev/null
+++ b/tenants/irestore4/custom-objects.mdx
@@ -0,0 +1,402 @@
+---
+title: "iRestore Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the iRestore data warehouse"
+icon: "database"
+---
+
+[← Back to iRestore](/tenants/irestore4) | [Open sm-irestore4 in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-irestore4)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for iRestore, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:46 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2scustomized_views) | 9 | 51,818 |
+| [`arslan_dataset`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2sarslan_dataset) | 2 | 37,261 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2ssm_sources) | 1 | 34,267 |
+| [`bi_playground`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2sbi_playground) | 2 | 6,771 |
+| [`custom_order_lines`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2scustom_order_lines) | 3 | 483 |
+| [`bi_expandfi_prod`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2sbi_expandfi_prod) | 6 | 315 |
+| [`custom_sources`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2scustom_sources) | 2 | 73 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 24,042
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3srpt_executive_summary_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.rpt_executive_summary_daily_customized` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 22,986
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3srpt_product_profit_and_loss)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.rpt_product_profit_and_loss` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4,508
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3srpt_ad_performance_with_product_type)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.rpt_ad_performance_with_product_type` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 87
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3sfulfil_order_lines_wip)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.fulfil_order_lines_wip` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 66
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3sobt_order_lines_w_cancelled_at)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.obt_order_lines_w_cancelled_at` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 55
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3slead_cap_rate_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.lead_cap_rate_table` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 34
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3sfulfil_missing_lines_check_wip)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.fulfil_missing_lines_check_wip` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 29
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3sfulfil_order_lines_with_cancel_status_wip)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.fulfil_order_lines_with_cancel_status_wip` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 11
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustomized_views!3sfulfil_refund_line_agg_wip)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.customized_views.fulfil_refund_line_agg_wip` LIMIT 10;
+```
+
+
+
+### arslan_dataset
+
+
+**Type:** BASE TABLE | **Queries (180d):** 36,732
+
+Custom data Key columns: `Date, Marketplace, ASIN, SKU, Name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sarslan_dataset!3sSB_SalesData)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.arslan_dataset.SB_SalesData` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 529
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sarslan_dataset!3sSB_Dump_Staging)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.arslan_dataset.SB_Dump_Staging` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** EXTERNAL | **Queries (180d):** 34,267
+
+Product/SKU-level data Key columns: `campaign_name, product_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2ssm_sources!3scustom_campaign_product_type_map)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.sm_sources.custom_campaign_product_type_map` LIMIT 10;
+```
+
+
+
+### bi_playground
+
+
+**Type:** VIEW | **Queries (180d):** 5,750
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_playground!3srpt_profit_and_loss_without_bundle)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_playground.rpt_profit_and_loss_without_bundle` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,021
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_playground!3srpt_profit_and_loss_without_bundle_parts)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_playground.rpt_profit_and_loss_without_bundle_parts` LIMIT 10;
+```
+
+
+
+### custom_order_lines
+
+
+**Type:** BASE TABLE | **Queries (180d):** 267
+
+Order-level data Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustom_order_lines!3sunified_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.custom_order_lines.unified_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 140
+
+Order-level data Key columns: `order_sku_id, order_name, flt_create_date, source_system, sm_store_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustom_order_lines!3sfulfil_order_lines_base)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.custom_order_lines.fulfil_order_lines_base` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 76
+
+Custom data Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustom_order_lines!3ssm_ol_with_fulfil_cogs)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.custom_order_lines.sm_ol_with_fulfil_cogs` LIMIT 10;
+```
+
+
+
+### bi_expandfi_prod
+
+
+**Type:** VIEW | **Queries (180d):** 139
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3svw_product_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.vw_product_summary` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 131
+
+Custom data Key columns: `amazon_order_item_id, created_at, updated_at, merchant_id, amazon_order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3ssales)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.sales` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 14
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3supsell_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.upsell_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Order-level data from Amazon Key columns: `amazon_order_id, merchant_order_id, purchase_date, last_updated_date, order_status`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3samazon_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.amazon_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 10
+
+Custom data Key columns: `amazon_order_item_id, created_at, updated_at, merchant_id, amazon_order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3ssales_transformed)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.sales_transformed` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 10
+
+Custom data Key columns: `name, promotion_type_friendly_name, discount_type, discount, new_subscriber_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2sbi_expandfi_prod!3spromotions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.bi_expandfi_prod.promotions` LIMIT 10;
+```
+
+
+
+### custom_sources
+
+
+**Type:** EXTERNAL | **Queries (180d):** 56
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustom_sources!3sbundle_part_mapping)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.custom_sources.bundle_part_mapping` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 17
+
+Order-level data Key columns: `Day, Discounts, Returns`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m5!1m4!4m3!1ssm-irestore4!2scustom_sources!3sorders_from_shopify)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-irestore4.custom_sources.orders_from_shopify` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-irestore4` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`irestore4`](https://console.cloud.google.com/bigquery?project=sm-irestore4&ws=!1m4!1m3!3m2!1ssm-irestore4!2sirestore4)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/neurogum.mdx b/tenants/neurogum.mdx
new file mode 100644
index 0000000..e685144
--- /dev/null
+++ b/tenants/neurogum.mdx
@@ -0,0 +1,52 @@
+---
+title: "Neuro Gum"
+sidebarTitle: "Neuro Gum"
+description: "Data documentation for Neuro Gum"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-neurogum in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-neurogum`](https://console.cloud.google.com/bigquery?project=sm-neurogum) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2ssm_transformed_v2) |
+| **Tenant ID** | `neurogum` |
diff --git a/tenants/neurogum/custom-objects.mdx b/tenants/neurogum/custom-objects.mdx
new file mode 100644
index 0000000..2583a5d
--- /dev/null
+++ b/tenants/neurogum/custom-objects.mdx
@@ -0,0 +1,667 @@
+---
+title: "Neuro Gum Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Neuro Gum data warehouse"
+icon: "database"
+---
+
+[← Back to Neuro Gum](/tenants/neurogum) | [Open sm-neurogum in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-neurogum)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Neuro Gum, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:46 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2scustomized_views) | 39 | 181,004 |
+| [`klaviyo`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2sklaviyo) | 3 | 8,594 |
+| [`northbeam_data`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2snorthbeam_data) | 2 | 46 |
+| [`sm_experimental`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2ssm_experimental) | 1 | 33 |
+| [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2ssm_transformed_v2) | 1 | 8 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 53,783
+
+Order-level data Key columns: `date, sm_channel, product_line, new_customers, new_user_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sorders_and_ads_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.orders_and_ads_summary` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 35,409
+
+Aggregated summary Key columns: `default_window, _1d_click, _7d_click, _1d_view, _7d_view`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3srpt_ad_performance_daily_with_sleep_core_campaign)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.rpt_ad_performance_daily_with_sleep_core_campaign` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 29,721
+
+Raw/native source data Key columns: `Date, Campaign_Name, Campaign_ID, Impressions, Clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sdsp_native)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.dsp_native` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 20,467
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3ssku_sales_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.sku_sales_summary` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 8,443
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sobt_order_lines_with_sleep_or_core)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.obt_order_lines_with_sleep_or_core` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,724
+
+Raw/native source data Key columns: `DATE, CAMPAIGN_NAME, CAMPAIGN_ID, IMPRESSIONS, CLICKS`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3spodscribe_native)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.podscribe_native` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4,424
+
+Denormalized "One Big Table" view Key columns: `WHEN, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sobt_orders_with_product_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.obt_orders_with_product_line` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 4,356
+
+Custom data Key columns: `Date, Campaign_Name, Campaign_ID, Impressions, Clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sdsp)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.dsp` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,413
+
+Customer-level data Key columns: `product_line, sm_channel, order_line_type, discount_category, first_order_month`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scustomer_lifetime_aggregates)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.customer_lifetime_aggregates` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,488
+
+Custom data Key columns: `standardized_sku, product_category, sm_channel, retention_month, total_cohort_size`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scohort_existing_to_target)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.cohort_existing_to_target` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,443
+
+Custom data Key columns: `standardized_sku, product_category, sm_channel, retention_month, total_cohort_size`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scohort_new_to_target)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.cohort_new_to_target` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2,193
+
+Customer-level data Key columns: `AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scustomer_lifetime_retention)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.customer_lifetime_retention` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2,113
+
+Custom data Key columns: `SELECT, ELSE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sweek_on_week_mtd)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.week_on_week_mtd` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,632
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sweek_on_week_performance)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.week_on_week_performance` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 957
+
+Weekly aggregation
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sweeklydata_visuals)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.weeklydata_visuals` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 636
+
+Custom data Key columns: `AND, AND, AND, WHERE, THEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sxeanalysis)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.xeanalysis` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 635
+
+Custom data Key columns: `customer_id, sku_combo, basket_size, days_to_repurchase, recency_bucket`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3srfm_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.rfm_table` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 467
+
+Monthly aggregation Key columns: `SELECT, SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3smonthly_ecomm_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.monthly_ecomm_summary` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 419
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3ssm_wg_analysis)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.sm_wg_analysis` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 368
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scodev_sku_metrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.codev_sku_metrics` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 330
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scustomertypecodev)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.customertypecodev` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 244
+
+Metrics definitions
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3score_metrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.core_metrics` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 242
+
+Metrics definitions Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scodev_total_metrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.codev_total_metrics` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 239
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scodevasket)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.codevasket` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 236
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scodevrepurchase)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.codevrepurchase` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 215
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scohort_ef_first_time)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.cohort_ef_first_time` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 133
+
+Custom data Key columns: `AND, AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sxeanalysis2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.xeanalysis2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 72
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3saovanalysis)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.aovanalysis` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 38
+
+Custom data Key columns: `AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sccretention)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.ccretention` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 26
+
+Customer-level data Key columns: `SELECT, AND, AND, AND, AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3schesspartnership_daily_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.chesspartnership_daily_customers` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 26
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3schesspartnership)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.chesspartnership` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 24
+
+Customer-level data Key columns: `consumer_id, acquisition_cohort, acquisition_year, acquisition_date, channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3scustomer_metrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.customer_metrics` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 21
+
+Customer-level data Key columns: `SELECT, AND, AND, AND, AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sneuroeventpartnership_daily_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.neuroeventpartnership_daily_customers` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 20
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sneuroeventpartnership)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.neuroeventpartnership` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 18
+
+Custom data from TikTok
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3stiktok_nb)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.tiktok_nb` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 13
+
+Aggregated summary Key columns: `WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3srpt_marketing_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.rpt_marketing_customized` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 9
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3spodscribe)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.podscribe` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 5
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3ssku_sales_summary_tt)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.sku_sales_summary_tt` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Order-level data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2scustomized_views!3sorders_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.customized_views.orders_summary` LIMIT 10;
+```
+
+
+
+### klaviyo
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,530
+
+Custom data from Klaviyo Key columns: `metric_id, profile_id, datetime, uuid`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2sklaviyo!3sklaviyo_event)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.klaviyo.klaviyo_event` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,830
+
+Custom data from Klaviyo Key columns: `external_id, email, phone_number, first_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2sklaviyo!3sklaviyo_profile)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.klaviyo.klaviyo_profile` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,234
+
+Metrics definitions from Klaviyo Key columns: `name, integration_id, integration_name, integration_category`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2sklaviyo!3sklaviyo_metric)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.klaviyo.klaviyo_metric` LIMIT 10;
+```
+
+
+
+### northbeam_data
+
+
+**Type:** BASE TABLE | **Queries (180d):** 33
+
+Order-level data Key columns: `discount_codes, product_id, order_id, customer_id, time_of_purchase`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2snorthbeam_data!3sttorders_to_nb)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.northbeam_data.ttorders_to_nb` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13
+
+Order-level data Key columns: `discount_codes, order_id, customer_id, time_of_purchase, customer_email`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2snorthbeam_data!3sorders_to_send)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.northbeam_data.orders_to_send` LIMIT 10;
+```
+
+
+
+### sm_experimental
+
+
+**Type:** BASE TABLE | **Queries (180d):** 33
+
+Denormalized "One Big Table" view from TikTok Key columns: `smcid, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2ssm_experimental!3sobt_tiktok_shop_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.sm_experimental.obt_tiktok_shop_orders` LIMIT 10;
+```
+
+
+
+### sm_transformed_v2
+
+
+**Type:** BASE TABLE | **Queries (180d):** 8
+
+Order-level data Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m5!1m4!4m3!1ssm-neurogum!2ssm_transformed_v2!3srevised_obt_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-neurogum.sm_transformed_v2.revised_obt_order_lines` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-neurogum` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`neurogum`](https://console.cloud.google.com/bigquery?project=sm-neurogum&ws=!1m4!1m3!3m2!1ssm-neurogum!2sneurogum)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/peoplebrandco.mdx b/tenants/peoplebrandco.mdx
new file mode 100644
index 0000000..2b29204
--- /dev/null
+++ b/tenants/peoplebrandco.mdx
@@ -0,0 +1,52 @@
+---
+title: "People Brand Co"
+sidebarTitle: "People Brand Co"
+description: "Data documentation for People Brand Co"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-peoplebrandco in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-peoplebrandco`](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m4!1m3!3m2!1ssm-peoplebrandco!2ssm_transformed_v2) |
+| **Tenant ID** | `peoplebrandco` |
diff --git a/tenants/peoplebrandco/custom-objects.mdx b/tenants/peoplebrandco/custom-objects.mdx
new file mode 100644
index 0000000..bb03472
--- /dev/null
+++ b/tenants/peoplebrandco/custom-objects.mdx
@@ -0,0 +1,161 @@
+---
+title: "People Brand Co Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the People Brand Co data warehouse"
+icon: "database"
+---
+
+[← Back to People Brand Co](/tenants/peoplebrandco) | [Open sm-peoplebrandco in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for People Brand Co, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m4!1m3!3m2!1ssm-peoplebrandco!2scustomized_views) | 6 | 12,838 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m4!1m3!3m2!1ssm-peoplebrandco!2ssm_sources) | 2 | 8,582 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,444
+
+Aggregated summary Key columns: `sm_store_id, source_system, sub_channel, date, ad_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3srpt_ad_performance_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.rpt_ad_performance_daily_customized` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,296
+
+Aggregated summary Key columns: `sm_store_id, sm_channel, sm_sub_channel, date, order_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3srpt_executive_summary_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.rpt_executive_summary_daily_customized` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,928
+
+Order-level data Key columns: `date, sm_store_id, sm_channel, order_id, repeat_cust_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3scustom_orders_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.custom_orders_table` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,585
+
+Aggregated summary Key columns: `date, sm_store_id, sm_channel, repeat_cust_orders, new_cust_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3srpt_klaviyo_customer_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.rpt_klaviyo_customer_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 474
+
+Order-level data Key columns: `date, sm_store_id, sm_channel, repeat_cust_orders, new_cust_orders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3sbeta_rpt_klaviyo_customer_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.beta_rpt_klaviyo_customer_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 111
+
+Aggregated summary Key columns: `date, sm_store_id, sm_channel, total_order_count, total_order_gross_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2scustomized_views!3srpt_avez_executive_summary_daily_customized)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.customized_views.rpt_avez_executive_summary_daily_customized` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** VIEW | **Queries (180d):** 4,291
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2ssm_sources!3sobt_klaviyo_subs_custs_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.sm_sources.obt_klaviyo_subs_custs_orders` LIMIT 10;
+```
+
+
+
+**Type:** CLONE | **Queries (180d):** 4,291
+
+Custom data Key columns: `event_properties, profile, timestamp, uuid`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m5!1m4!4m3!1ssm-peoplebrandco!2ssm_sources!3ssrc_klaviyo__subscribe_list)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-peoplebrandco.sm_sources.src_klaviyo__subscribe_list` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-peoplebrandco` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`peoplebrandco`](https://console.cloud.google.com/bigquery?project=sm-peoplebrandco&ws=!1m4!1m3!3m2!1ssm-peoplebrandco!2speoplebrandco)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/pillar3cx.mdx b/tenants/pillar3cx.mdx
new file mode 100644
index 0000000..de41e28
--- /dev/null
+++ b/tenants/pillar3cx.mdx
@@ -0,0 +1,52 @@
+---
+title: "Pillar3CX"
+sidebarTitle: "Pillar3CX"
+description: "Data documentation for Pillar3CX"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-pillar3cx in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-pillar3cx`](https://console.cloud.google.com/bigquery?project=sm-pillar3cx) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m4!1m3!3m2!1ssm-pillar3cx!2ssm_transformed_v2) |
+| **Tenant ID** | `pillar3cx` |
diff --git a/tenants/pillar3cx/custom-objects.mdx b/tenants/pillar3cx/custom-objects.mdx
new file mode 100644
index 0000000..982ef4b
--- /dev/null
+++ b/tenants/pillar3cx/custom-objects.mdx
@@ -0,0 +1,157 @@
+---
+title: "Pillar 3CX Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Pillar 3CX data warehouse"
+icon: "database"
+---
+
+[← Back to Pillar 3CX](/tenants/pillar3cx) | [Open sm-pillar3cx in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Pillar 3CX, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:48 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m4!1m3!3m2!1ssm-pillar3cx!2ssm_transformed_v2) | 8 | 2,107 |
+
+---
+
+## Objects by Dataset
+
+### sm_transformed_v2
+
+
+**Type:** VIEW | **Queries (180d):** 698
+
+Custom data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_cx_aggregate)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_cx_aggregate` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 680
+
+Custom data Key columns: `_airbyte_raw_id, _airbyte_extracted_at, _airbyte_generation_id, uri`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_ticket)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_ticket` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 588
+
+Customer-level data Key columns: `_airbyte_raw_id, _airbyte_extracted_at, _airbyte_generation_id, uri`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_customer_satisfaction)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_customer_satisfaction` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 100
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_defect_category)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_defect_category` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 12
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_transpo_defect)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_transpo_defect` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 11
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_csat)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_csat` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 10
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_defect_by_sku_by_day)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_defect_by_sku_by_day` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 8
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m5!1m4!4m3!1ssm-pillar3cx!2ssm_transformed_v2!3sbuyfuelmeals_defect_pivot)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-pillar3cx.sm_transformed_v2.buyfuelmeals_defect_pivot` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-pillar3cx` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`pillar3cx`](https://console.cloud.google.com/bigquery?project=sm-pillar3cx&ws=!1m4!1m3!3m2!1ssm-pillar3cx!2spillar3cx)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/piquetea.mdx b/tenants/piquetea.mdx
new file mode 100644
index 0000000..da00f5a
--- /dev/null
+++ b/tenants/piquetea.mdx
@@ -0,0 +1,52 @@
+---
+title: "Pique Tea"
+sidebarTitle: "Pique Tea"
+description: "Data documentation for Pique Tea"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-piquetea in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-piquetea`](https://console.cloud.google.com/bigquery?project=sm-piquetea) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m4!1m3!3m2!1ssm-piquetea!2ssm_transformed_v2) |
+| **Tenant ID** | `piquetea` |
diff --git a/tenants/piquetea/custom-objects.mdx b/tenants/piquetea/custom-objects.mdx
new file mode 100644
index 0000000..ff69e8c
--- /dev/null
+++ b/tenants/piquetea/custom-objects.mdx
@@ -0,0 +1,854 @@
+---
+title: "Pique Tea Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the Pique Tea data warehouse"
+icon: "database"
+---
+
+[← Back to Pique Tea](/tenants/piquetea) | [Open sm-piquetea in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-piquetea)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for Pique Tea, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m4!1m3!3m2!1ssm-piquetea!2scustomized_views) | 57 | 174,725 |
+| [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m4!1m3!3m2!1ssm-piquetea!2ssm_transformed_v2) | 1 | 103 |
+| [`analytics_311213792`](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m4!1m3!3m2!1ssm-piquetea!2sanalytics_311213792) | 3 | 28 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 62,128
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sobt_orders_device_type_updated)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.obt_orders_device_type_updated` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 24,152
+
+Custom data Key columns: `id_key, conversion_date, conversion_id, order_no, affiliate_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_fivetran_replacement)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_fivetran_replacement` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 7,907
+
+Custom data Key columns: `date, customer_status, action_cost, revenue, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3simpact_daily_automation)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.impact_daily_automation` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 7,882
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_orders_rev)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_orders_rev` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 7,874
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_commission)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_commission` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 7,163
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3ssc_sku_breakdown_v4)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.sc_sku_breakdown_v4` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4,575
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sdaily_data_v5_online_dtc_slice)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.daily_data_v5_online_dtc_slice` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 4,233
+
+Custom data Key columns: `Date, Month, Year, Week, YT_Spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_impact_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_impact_table` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4,067
+
+Custom data Key columns: `WHEN, WHEN, WHEN, WHERE, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sseven_day_cancels_revision5)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.seven_day_cancels_revision5` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 3,940
+
+Custom data Key columns: `AFFILIATE_ID, AFFILIATE_NAME, UTM_CONTENT_FINAL, ORDER_DATE, COMMISSION_TOTAL`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_partner_final_v3_0522)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_partner_final_v3_0522` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3,737
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sdaily_data_v4_line_spend_slice)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.daily_data_v4_line_spend_slice` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3,735
+
+Custom data from Amazon
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sdaily_data_v5_amazon_slice)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.daily_data_v5_amazon_slice` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 3,553
+
+Custom data Key columns: `AFFILIATE_ID, AFFILIATE_NAME, UTM_CONTENT_FINAL, ORDER_DATE, COMMISSION_TOTAL`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_partner_final)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_partner_final` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 3,404
+
+Custom data Key columns: `channel, month, date, network, deliverable`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3snick_import_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.nick_import_v1` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 3,398
+
+Custom data Key columns: `channel, year, month, name, handle`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srylie_import_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.rylie_import_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3,106
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sklaviyo_attentive_reporting)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.klaviyo_attentive_reporting` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 2,273
+
+Custom data Key columns: `DATE, UTM_CONTENT, SESSIONS`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_sessions_temp)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_sessions_temp` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,908
+
+Aggregated summary
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srpt_exec_to_order_test)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.rpt_exec_to_order_test` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 1,842
+
+Custom data Key columns: `utm_content, day, utm_medium, Sessions`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sall_parnterships_refersion_sessions_temp_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.all_parnterships_refersion_sessions_temp_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,783
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_partner_spend_podonly_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_partner_spend_podonly_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,739
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sall_partnerships_refersion_sessions_performanceoverview)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.all_partnerships_refersion_sessions_performanceoverview` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,644
+
+Custom data Key columns: `AND`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sall_channel_partnerships_data_v4)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.all_channel_partnerships_data_v4` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,265
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sRylie_Refersion_Daily_Partner_Level_V2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.Rylie_Refersion_Daily_Partner_Level_V2` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 1,180
+
+Custom data Key columns: `AFFILIATE_ID, AFFILIATE_NAME, UTM_CONTENT_FINAL, ORDER_DATE, COMMISSION_TOTAL`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srefersion_partner_final_v2_0516)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.refersion_partner_final_v2_0516` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,151
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sRylie_Partnerships_Sessions_Temp)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.Rylie_Partnerships_Sessions_Temp` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1,077
+
+Custom data Key columns: `WHERE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3spartener_ltv_view_v5_automate_sidetable)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.partener_ltv_view_v5_automate_sidetable` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 893
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3saffiliate_id_mapping_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.affiliate_id_mapping_v1` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 343
+
+Custom data Key columns: `date, week, month, quarter, year`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3schurn_export_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.churn_export_v2` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 326
+
+Custom data Key columns: `date, total_referral_rev, total_ft_referral_rev, total_recurring_referral_rev, total_rev_shopify`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sreferral_program_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.referral_program_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 307
+
+Custom data Key columns: `WHERE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3spartnerships_ltv_v5)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.partnerships_ltv_v5` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 300
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3ssuperfiliate_base_orders_rev)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.superfiliate_base_orders_rev` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 294
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3ssuperfiliate_recurring_subs_orders_rev)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.superfiliate_recurring_subs_orders_rev` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 277
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sreferral_program_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.referral_program_v2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 173
+
+Custom data Key columns: `WHEN, WHEN, WHEN, WHERE, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sseven_day_cancellation_channel_revised)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.seven_day_cancellation_channel_revised` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 107
+
+Custom data Key columns: `date, direct, email, twitter, facebook`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sloyaltylion_referrals)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.loyaltylion_referrals` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 103
+
+Custom data Key columns: `WHEN, WHEN, WHEN, WHERE, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sseven_day_cancels_revision_two)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.seven_day_cancels_revision_two` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 101
+
+Custom data Key columns: `month_date, month_label, active_subscribers, churn_rate`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3schurn_export_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.churn_export_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 97
+
+Order-level data Key columns: `ON, ON, ON`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sgwp_obt_orders_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.gwp_obt_orders_v2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 91
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sall_partnerships_channel_sessions_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.all_partnerships_channel_sessions_v2` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 84
+
+Product/SKU-level data Key columns: `product_title, variant_tax_code`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sproduct_tax_codes)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.product_tax_codes` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 63
+
+Marketing/advertising data Key columns: `channel, partnerships_lead, campaign_name, superfiliate_code, date`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3ssuperfiliate_go_live_spend)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.superfiliate_go_live_spend` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 57
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3srecurring_subs_over100)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.recurring_subs_over100` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 52
+
+Custom data Key columns: `message_send_date, message_variant, has_media, deliveries, total_clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sattentive_table_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.attentive_table_v1` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 43
+
+Aggregated summary Key columns: `AFFILIATE_ID, AFFILIATE_NAME, CHANNEL_TAG, REFERRALS, OTP_ORDERS`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3spique_referral_summary)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.pique_referral_summary` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 38
+
+Custom data Key columns: `message_send_date, message_variant, has_media, deliveries, total_clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sattentive_data_sync_draft)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.attentive_data_sync_draft` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 36
+
+Custom data Key columns: `WHEN, WHEN, WHEN, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sseven_day_cancels)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.seven_day_cancels` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 35
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sobt_orders_gwp_updates_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.obt_orders_gwp_updates_v2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 35
+
+Custom data Key columns: `WHERE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3spartnership_ltv_v3)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.partnership_ltv_v3` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 34
+
+Custom data Key columns: `WHEN, WHEN, WHEN, WHERE, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sseven_day_cancels_revision3)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.seven_day_cancels_revision3` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 31
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sLTV_Retention_AOV_View)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.LTV_Retention_AOV_View` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 30
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sobt_orders_gwp_updates)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.obt_orders_gwp_updates` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 23
+
+Product/SKU-level data Key columns: `WHEN, WHEN, WHEN, WHEN, WHEN`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sretention_rate_by_product_noncancelled)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.retention_rate_by_product_noncancelled` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 12
+
+Custom data Key columns: `event_date, event_timestamp, event_name, event_params, event_previous_timestamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sga4_events_raw)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.ga4_events_raw` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Marketing/advertising data Key columns: `sn_order_id, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sadhoc_zach-012626)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.adhoc_zach-012626` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 9
+
+Marketing/advertising data Key columns: `utm_medium, month, sessions`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3straffic_partnerships_adhoc)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.traffic_partnerships_adhoc` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Order-level data Key columns: `ON`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sgwp_obt_orders_totals_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.gwp_obt_orders_totals_v2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2scustomized_views!3sobt_orders_previous_subscriber_updated)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.customized_views.obt_orders_previous_subscriber_updated` LIMIT 10;
+```
+
+
+
+### sm_transformed_v2
+
+
+**Type:** BASE TABLE | **Queries (180d):** 103
+
+Aggregated summary Key columns: `sm_store_id, cohort_filter_name_filter_value_month_id, cohort_filter_name_filter_value_id, cohort_month, months_since_first_order`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2ssm_transformed_v2!3srpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.sm_transformed_v2.rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters_v1` LIMIT 10;
+```
+
+
+
+### analytics_311213792
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `event_date, event_timestamp, event_name, event_params, event_previous_timestamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2sanalytics_311213792!3sevents_20251022)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.analytics_311213792.events_20251022` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 10
+
+Custom data Key columns: `event_date, event_timestamp, event_name, event_params, event_previous_timestamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2sanalytics_311213792!3sevents_20250930)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.analytics_311213792.events_20250930` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7
+
+Custom data Key columns: `event_date, event_timestamp, event_name, event_params, event_previous_timestamp`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m5!1m4!4m3!1ssm-piquetea!2sanalytics_311213792!3sevents_20260120)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-piquetea.analytics_311213792.events_20260120` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-piquetea` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`piquetea`](https://console.cloud.google.com/bigquery?project=sm-piquetea&ws=!1m4!1m3!3m2!1ssm-piquetea!2spiquetea)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/theperfectjean.mdx b/tenants/theperfectjean.mdx
new file mode 100644
index 0000000..4d30da9
--- /dev/null
+++ b/tenants/theperfectjean.mdx
@@ -0,0 +1,52 @@
+---
+title: "The Perfect Jean"
+sidebarTitle: "The Perfect Jean"
+description: "Data documentation for The Perfect Jean"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-theperfectjean in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-theperfectjean`](https://console.cloud.google.com/bigquery?project=sm-theperfectjean) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m4!1m3!3m2!1ssm-theperfectjean!2ssm_transformed_v2) |
+| **Tenant ID** | `theperfectjean` |
diff --git a/tenants/theperfectjean/custom-objects.mdx b/tenants/theperfectjean/custom-objects.mdx
new file mode 100644
index 0000000..458eea4
--- /dev/null
+++ b/tenants/theperfectjean/custom-objects.mdx
@@ -0,0 +1,174 @@
+---
+title: "The Perfect Jean Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the The Perfect Jean data warehouse"
+icon: "database"
+---
+
+[← Back to The Perfect Jean](/tenants/theperfectjean) | [Open sm-theperfectjean in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for The Perfect Jean, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:46 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m4!1m3!3m2!1ssm-theperfectjean!2scustomized_views) | 8 | 54 |
+| [`sm_views`](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m4!1m3!3m2!1ssm-theperfectjean!2ssm_views) | 1 | 13 |
+
+---
+
+## Objects by Dataset
+
+### customized_views
+
+
+**Type:** VIEW | **Queries (180d):** 15
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3ssessions_rev_by_country)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.sessions_rev_by_country` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 13
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3sjosh_module_logic1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.josh_module_logic1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 9
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3sjosh_module_logic_2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.josh_module_logic_2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 6
+
+Custom data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3sshirt_unbundler_v2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.shirt_unbundler_v2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 4
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3sshirt_unbundler_v1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.shirt_unbundler_v1` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3
+
+Order-level data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3sorder_by_types_week)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.order_by_types_week` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Order-level data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3stypes_per_order)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.types_per_order` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Order-level data Key columns: `SELECT`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2scustomized_views!3stypes_per_order_month)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.customized_views.types_per_order_month` LIMIT 10;
+```
+
+
+
+### sm_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 13
+
+Custom data Key columns: `date, body, title, rating, status`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m5!1m4!4m3!1ssm-theperfectjean!2ssm_views!3sokendo_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-theperfectjean.sm_views.okendo_data` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-theperfectjean` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`theperfectjean`](https://console.cloud.google.com/bigquery?project=sm-theperfectjean&ws=!1m4!1m3!3m2!1ssm-theperfectjean!2stheperfectjean)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/xcvi.mdx b/tenants/xcvi.mdx
new file mode 100644
index 0000000..68bb53b
--- /dev/null
+++ b/tenants/xcvi.mdx
@@ -0,0 +1,52 @@
+---
+title: "XCVI"
+sidebarTitle: "XCVI"
+description: "Data documentation for XCVI"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-xcvi in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-xcvi`](https://console.cloud.google.com/bigquery?project=sm-xcvi) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssm_transformed_v2) |
+| **Tenant ID** | `xcvi` |
diff --git a/tenants/xcvi/custom-objects.mdx b/tenants/xcvi/custom-objects.mdx
new file mode 100644
index 0000000..7ce933f
--- /dev/null
+++ b/tenants/xcvi/custom-objects.mdx
@@ -0,0 +1,1535 @@
+---
+title: "XCVI Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the XCVI data warehouse"
+icon: "database"
+---
+
+[← Back to XCVI](/tenants/xcvi) | [Open sm-xcvi in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-xcvi)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for XCVI, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`n41_mssql_data2`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sn41_mssql_data2) | 13 | 18,241 |
+| [`sell_through_data`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssell_through_data) | 8 | 15,143 |
+| [`n41_data`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sn41_data) | 9 | 10,412 |
+| [`so_detail_pipeline`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sso_detail_pipeline) | 20 | 10,160 |
+| [`n41_mssql_data3`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sn41_mssql_data3) | 7 | 5,672 |
+| [`customized_views`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2scustomized_views) | 8 | 5,619 |
+| [`sell_through_pipeline`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssell_through_pipeline) | 12 | 4,417 |
+| [`N41_created_reports`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sN41_created_reports) | 12 | 3,898 |
+| [`v_inventory_pos_by_wh`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sv_inventory_pos_by_wh) | 9 | 3,742 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssm_sources) | 2 | 2,981 |
+| [`snowflake_data`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssnowflake_data) | 7 | 1,972 |
+| [`sm_experimental`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2ssm_experimental) | 1 | 96 |
+| [`n41_transfer_data`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sn41_transfer_data) | 1 | 91 |
+| [`DL_XCVI`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sDL_XCVI) | 1 | 10 |
+
+---
+
+## Objects by Dataset
+
+### n41_mssql_data2
+
+
+**Type:** BASE TABLE | **Queries (180d):** 6,215
+
+Custom data Key columns: `table_name, column_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3s_sdc_primary_keys)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2._sdc_primary_keys` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,856
+
+Custom data Key columns: `sono, unit14, unit13, unit9, bundleperbox`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_POD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_POD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,588
+
+Custom data Key columns: `sono, unit14, radid, invoiceno, extprice`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_INVD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_INVD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,425
+
+Custom data Key columns: `canceldate, unit14, invoiceno, extprice, unit13`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_SOD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_SOD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,377
+
+Custom data Key columns: `poclunit13, unit14, pr_line, unit13, damagereason`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_inventory)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_inventory` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,119
+
+Custom data Key columns: `canceldate, dc, memocode, comrate2, cit_app_code`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_SOH)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_SOH` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 941
+
+Customer-level data Key columns: `web_password, fax1, salesrep1rate, memocode, user3`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_customer)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_customer` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 820
+
+Custom data Key columns: `total, canceldate, dc, comrate4, invoiceno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_INV)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_INV` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 817
+
+Custom data Key columns: `sono, unit14, unit13, unit9, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_pickD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_pickD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 772
+
+Custom data Key columns: `canceldate, unit14, invoiceno, extprice, unit13`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_SOSD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_SOSD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 760
+
+Custom data Key columns: `size20, size14, size2, size24, size7`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_size)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_size` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 365
+
+Custom data Key columns: `code, descript, _sdc_received_at, _sdc_sequence, _sdc_batched_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_cancelReason)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_cancelReason` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 186
+
+Custom data Key columns: `sono, unit14, unit13, unit9, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data2!3sNVLT_AllocateD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data2.NVLT_AllocateD` LIMIT 10;
+```
+
+
+
+### sell_through_data
+
+
+**Type:** BASE TABLE | **Queries (180d):** 12,059
+
+Custom data Key columns: `sm_store_id, transaction_date, sku, order_quantity, order_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3sxcvi_final_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.xcvi_final_table` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,733
+
+Custom data Key columns: `date_index, sku, inventory_item_id, color, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3sinventory_spine_v3)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.inventory_spine_v3` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 478
+
+Custom data Key columns: `Order_Number, Order_Type, SKU, Line_Number, Style_Code`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3secom_so_qty_latest)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.ecom_so_qty_latest` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 386
+
+Product/SKU-level data Key columns: `date_index, sku, inventory_item_id, color, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3ssku_date_combinations)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.sku_date_combinations` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 218
+
+Custom data Key columns: `sm_store_id, transaction_date, sku, order_quantity, order_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3stransaction_union)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.transaction_union` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 211
+
+Custom data Key columns: `SKU, dropdate, catalog_flag, primary_product_image_url, product_tags`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3sdrop_date_catalog_flag_processing)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.drop_date_catalog_flag_processing` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 47
+
+Custom data Key columns: `inventory_style, sm_store_id, transaction_date, order_quantity, order_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3sfinal_table_style_aggregate)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.final_table_style_aggregate` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `inventory_item_id, effective_date, available, sku`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_data!3secom_inventory_spine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_data.ecom_inventory_spine` LIMIT 10;
+```
+
+
+
+### n41_data
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,997
+
+Custom data Key columns: `table_name, column_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3s_sdc_primary_keys)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data._sdc_primary_keys` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,014
+
+Custom data Key columns: `order4, vendorpart1, rawmattype, pick1, order15`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_styleColor)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_styleColor` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 675
+
+Custom data Key columns: `code, size, sorder, __sdc_primary_key, _sdc_received_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sv_size_vertical)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.v_size_vertical` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 612
+
+Custom data Key columns: `vendor, cuser, edi_descript, nrf, vendor_code2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_color)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_color` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 582
+
+Custom data Key columns: `color_nrf, ptype, _sdc_table_version, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_UPC)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_UPC` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 538
+
+Custom data Key columns: `f_non_factor_pm, f_non_factor_cm, f_factor_inv, fax1, t_po`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_division)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_division` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 366
+
+Custom data Key columns: `size20, size14, size2, size24, size7`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_size)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_size` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 328
+
+Custom data Key columns: `sort_code, todate, _sdc_table_version, _sdc_received_at, _sdc_sequence`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_season)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_season` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 300
+
+Custom data Key columns: `sono, unit14, actual_cost_conf, unit13, unit9`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_data!3sNVLT_POD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_data.NVLT_POD` LIMIT 10;
+```
+
+
+
+### so_detail_pipeline
+
+
+**Type:** BASE TABLE | **Queries (180d):** 916
+
+Custom data Key columns: `sono, unit14, radid, invoiceno, extprice`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sinvd)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.invd` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 623
+
+Custom data Key columns: `canceldate, unit14, invoiceno, extprice, unit13`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3ssosd)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.sosd` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 619
+
+Custom data Key columns: `total, canceldate, dc, comrate4, invoiceno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sinv)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.inv` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 613
+
+Custom data Key columns: `sono, unit14, unit13, unit9, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sallocated)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.allocated` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 472
+
+Custom data Key columns: `canceldate, unit14, invoiceno, extprice, unit13`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3ssod)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.sod` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 469
+
+Custom data Key columns: `canceldate, dc, memocode, comrate2, cit_app_code`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3ssoh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.soh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 467
+
+Custom data Key columns: `order4, vendorpart1, rawmattype, pick1, order15`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sstylecolor)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.stylecolor` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 463
+
+Custom data Key columns: `sono, canceldate, user3, user2, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3spickh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.pickh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 463
+
+Custom data Key columns: `size20, size14, size2, size24, size7`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3ssize_dedup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.size_dedup` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 463
+
+Customer-level data Key columns: `web_password, fax1, salesrep1rate, memocode, user3`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3scustomer)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.customer` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 460
+
+Custom data Key columns: `orderno, orderType, division, orderdate, shipdate`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sso_detail_final)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.so_detail_final` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 460
+
+Metrics definitions Key columns: `pono, style, color, po_qty, po_price`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_po_metrics)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_po_metrics` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sodid, inv_qty, inv_amt`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_invd_by_sod)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_invd_by_sod` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sono, invoiceno, cmno, invoicedate, inv_status`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_inv_hdr)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_inv_hdr` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sodid, allo_qty`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_alloc)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_alloc` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sodid, ship_qty`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_ship)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_ship` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `style, color, last_open_eta, first_open_eta`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_po_eta)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_po_eta` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sono, sodid, invUnit1, invUnit2, invUnit3`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_invd_by_sono_sod)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_invd_by_sono_sod` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `sodid, pick_qty`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_pick)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_pick` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 459
+
+Custom data Key columns: `style, color, last_received_date`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sso_detail_pipeline!3sagg_last_received)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.so_detail_pipeline.agg_last_received` LIMIT 10;
+```
+
+
+
+### n41_mssql_data3
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,511
+
+Custom data Key columns: `table_name, column_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3s_sdc_primary_keys)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3._sdc_primary_keys` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,013
+
+Custom data Key columns: `house_only, sono, bldate, onboarddate, canceldate`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_POH)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_POH` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 789
+
+Custom data Key columns: `oh1, recalcupddt, warehouse, inventoryupddt, oh3`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_INVENTORY_BY_WH)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_INVENTORY_BY_WH` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 603
+
+Custom data Key columns: `sono, canceldate, user3, user2, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_pickH)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_pickH` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 366
+
+Custom data Key columns: `canceldate, unit14, invoiceno, extprice, unit13`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_SOD_LOG)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_SOD_LOG` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 350
+
+Custom data Key columns: `sono, unit14, unit13, unit9, pickno`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_AllocateD)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_AllocateD` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 40
+
+Customer-level data Key columns: `customer, _sdc_table_version, _sdc_received_at, _sdc_sequence, _sdc_batched_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_mssql_data3!3sNVLT_customer_div)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_mssql_data3.NVLT_customer_div` LIMIT 10;
+```
+
+
+
+### customized_views
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,822
+
+Product/SKU-level data Key columns: `sku, style, color, color_description, size`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sSKU_RAW_N41)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.SKU_RAW_N41` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 769
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sSKU_master_BQ)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.SKU_master_BQ` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 377
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sN41_Last_PO_Price)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.N41_Last_PO_Price` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 232
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sexecutive_sheet_source)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.executive_sheet_source` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 186
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sN41_product_detail_wringerwear)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.N41_product_detail_wringerwear` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 174
+
+Custom data Key columns: `row_uid, pono, pod_status, poh_status, orderdate`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3sPO_Register_Detail-open-WIP)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.PO_Register_Detail-open-WIP` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 52
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3score_trend_dataset)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.core_trend_dataset` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7
+
+Product/SKU-level data Key columns: `sku, inventory_item_id, product_cost`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2scustomized_views!3slatest_product_cost_by_sku)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.customized_views.latest_product_cost_by_sku` LIMIT 10;
+```
+
+
+
+### sell_through_pipeline
+
+
+**Type:** BASE TABLE | **Queries (180d):** 912
+
+Custom data Key columns: `transaction_date, sku, sm_store_id, order_quantity, order_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3ssell_through_pipeline_final_table)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.sell_through_pipeline_final_table` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 568
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3ssku_master_BQ_pipeline)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.sku_master_BQ_pipeline` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 518
+
+Custom data Key columns: `date_index, sku, inventory_item_id, color, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3secom_inventory_spine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.ecom_inventory_spine` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 429
+
+Product/SKU-level data Key columns: `date_index, sku, inventory_item_id, color, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3ssku_date_combinations)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.sku_date_combinations` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 405
+
+Custom data Key columns: `sm_store_id, transaction_date, sku, order_quantity, order_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3spipeline_transaction_union)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.pipeline_transaction_union` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 275
+
+Custom data Key columns: `SKU, dropdate, catalog_flag, primary_product_image_url, product_tags`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3sdrop_date_catalog_processing)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.drop_date_catalog_processing` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 263
+
+Custom data Key columns: `color_nrf, ptype, _sdc_table_version, style`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3sNVLT_UPC_deduped)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.NVLT_UPC_deduped` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 260
+
+Custom data Key columns: `sort_code, todate, _sdc_table_version, _sdc_received_at, _sdc_sequence`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3sNVLT_season_deduped)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.NVLT_season_deduped` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 260
+
+Custom data Key columns: `f_non_factor_pm, f_non_factor_cm, f_factor_inv, fax1, t_po`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3snvlt_division_deduped)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.nvlt_division_deduped` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 260
+
+Product/SKU-level data Key columns: `sku, style, color, color_description, size`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3ssku_raw_n41)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.sku_raw_n41` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 260
+
+Custom data Key columns: `code, size, sorder, __sdc_primary_key, _sdc_received_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3sv_size_vertical_deduped)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.v_size_vertical_deduped` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssell_through_pipeline!3ssku_master_BQ_st_pipeline)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sell_through_pipeline.sku_master_BQ_st_pipeline` LIMIT 10;
+```
+
+
+
+### N41_created_reports
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,208
+
+Custom data Key columns: `SKU, Style, Color, category, Color_Desc`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sN41_Inventory_Vertical)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.N41_Inventory_Vertical` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 391
+
+Custom data Key columns: `style, color, wh, onorder1, onorder2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_so_detail_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_so_detail_by_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 387
+
+Custom data Key columns: `style, color, wh, wip1, wip2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_po_detail_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_po_detail_by_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 375
+
+Custom data Key columns: `style, color, wh, unit1, unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_cm_inventory_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_cm_inventory_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 375
+
+Custom data Key columns: `style, color, wh, unit1, unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_inv_inventory_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_inv_inventory_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 367
+
+Custom data Key columns: `style, color, category, color_desc, price1`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_inventory_position_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_inventory_position_by_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 192
+
+Custom data Key columns: `customer_code, customer_name, division, so_type, year`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_sales_by_quarter_sotype_division_alldetail)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_sales_by_quarter_sotype_division_alldetail` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 181
+
+Custom data Key columns: `style, color, wh, unit1, unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_sos_stylecolor_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_sos_stylecolor_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 181
+
+Custom data Key columns: `style, color, wh, unit1, unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_pick_stylecolor_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_pick_stylecolor_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 181
+
+Custom data Key columns: `style, color, wh, unit1, unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_alloc_stylecolor_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_alloc_stylecolor_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 57
+
+Custom data Key columns: `Contact1, Adress1, State, Dvision, Customer_Type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sAida_SeasondateV2)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.Aida_SeasondateV2` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 3
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sN41_created_reports!3sv_inv_detail_2_4NORDDROP)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.N41_created_reports.v_inv_detail_2_4NORDDROP` LIMIT 10;
+```
+
+
+
+### v_inventory_pos_by_wh
+
+
+**Type:** BASE TABLE | **Queries (180d):** 528
+
+Custom data Key columns: `order4, vendorpart1, rawmattype, pick1, order15`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_deduped_stylecolor)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_deduped_stylecolor` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 523
+
+Custom data Key columns: `code, descript, _sdc_batched_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_deduped_color)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_deduped_color` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 395
+
+Custom data Key columns: `oh1, recalcupddt, warehouse, inventoryupddt, oh3`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_deduped_inventory_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_deduped_inventory_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 395
+
+Custom data Key columns: `size20, size14, size2, size24, size7`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_deduped_size)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_deduped_size` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 394
+
+Custom data Key columns: `style, color, warehouse, inv_unit1, inv_unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_invoice_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_invoice_by_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 393
+
+Custom data Key columns: `style, color, first_eta`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_first_eta)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_first_eta` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 393
+
+Custom data Key columns: `style, color, warehouse, cm_unit1, cm_unit2`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_cm_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_cm_by_wh` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 383
+
+Custom data Key columns: `sono, unit14, unit13, unit9, bundleperbox`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_deduped_pod)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_deduped_pod` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 338
+
+Custom data Key columns: `style, color, category, color_desc, price1`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sv_inventory_pos_by_wh!3sv_inventory_pos_by_wh)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.v_inventory_pos_by_wh.v_inventory_pos_by_wh` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,564
+
+Product/SKU-level data Key columns: `sku, image_url, sm_store_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssm_sources!3sxcvi_product_images)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sm_sources.xcvi_product_images` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 417
+
+Custom data Key columns: `smcid, sm_inventory_level_history_id, sm_inventory_level_hash_id, sm_channel, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssm_sources!3ssm_inventory_tables)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sm_sources.sm_inventory_tables` LIMIT 10;
+```
+
+
+
+### snowflake_data
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,299
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sSKU_MASTER1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.SKU_MASTER1` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 233
+
+Product/SKU-level data Key columns: `ID, SKU, TITLE, BODY_HTML, VENDOR`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sTFT_SKU)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.TFT_SKU` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 233
+
+Product/SKU-level data Key columns: `ID, SKU, TITLE, BODY_HTML, VENDOR`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sXC_SHOPIFY_SKU1)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.XC_SHOPIFY_SKU1` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 73
+
+Custom data Key columns: `ORDERNO, ORDERTYPE, SKU, LINE, STYLE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sN41_ECOM_SO)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.N41_ECOM_SO` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 52
+
+Custom data Key columns: `SKU, STYLE, COLOR, CATEGORY, COLOR_DESC`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sN41_INV_VERTICAL)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.N41_INV_VERTICAL` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 52
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sSKU_MASTER)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.SKU_MASTER` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 30
+
+Product/SKU-level data Key columns: `SKU, STYLE, COLOR, COLOR_DESCRIPTION, SIZE`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssnowflake_data!3sN41_SKU_RAW)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.snowflake_data.N41_SKU_RAW` LIMIT 10;
+```
+
+
+
+### sm_experimental
+
+
+**Type:** BASE TABLE | **Queries (180d):** 96
+
+Custom data Key columns: `name, sku, total_on_hand_quantity, total_committed_quantity, total_fulfillable_quantity`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2ssm_experimental!3sshipbob_inventory_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.sm_experimental.shipbob_inventory_data` LIMIT 10;
+```
+
+
+
+### n41_transfer_data
+
+
+**Type:** BASE TABLE | **Queries (180d):** 91
+
+Custom data Key columns: `so_balanced_amount, sku, city, customer_type, cm_`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sn41_transfer_data!3sv_sales_by_quarter_sotype_division_alldetail_v4)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.n41_transfer_data.v_sales_by_quarter_sotype_division_alldetail_v4` LIMIT 10;
+```
+
+
+
+### DL_XCVI
+
+
+**Type:** VIEW | **Queries (180d):** 10
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m5!1m4!4m3!1ssm-xcvi!2sDL_XCVI!3sXCVI_Shopify_Inv_Not_snowflake)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-xcvi.DL_XCVI.XCVI_Shopify_Inv_Not_snowflake` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-xcvi` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`xcvi`](https://console.cloud.google.com/bigquery?project=sm-xcvi&ws=!1m4!1m3!3m2!1ssm-xcvi!2sxcvi)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tenants/zbiotics.mdx b/tenants/zbiotics.mdx
new file mode 100644
index 0000000..4d29b0a
--- /dev/null
+++ b/tenants/zbiotics.mdx
@@ -0,0 +1,52 @@
+---
+title: "ZBiotics"
+sidebarTitle: "ZBiotics"
+description: "Data documentation for ZBiotics"
+icon: "building"
+---
+
+
+This documentation is not publicly listed and is accessible only via direct URL.
+
+
+## Quick Access
+
+
+
+ Open sm-zbiotics in BigQuery Console
+
+
+ View custom tables and views
+
+
+ sm_transformed_v2 documentation
+
+
+ Platform setup and configuration
+
+
+
+## Resources
+
+
+
+ Customize channel mapping, attribution, and more
+
+
+ Looker Studio module documentation
+
+
+ Diagnose and improve tracking coverage
+
+
+ FAQs and troubleshooting
+
+
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | [`sm-zbiotics`](https://console.cloud.google.com/bigquery?project=sm-zbiotics) |
+| **Standard Dataset** | [`sm_transformed_v2`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2ssm_transformed_v2) |
+| **Tenant ID** | `zbiotics` |
diff --git a/tenants/zbiotics/custom-objects.mdx b/tenants/zbiotics/custom-objects.mdx
new file mode 100644
index 0000000..d449a77
--- /dev/null
+++ b/tenants/zbiotics/custom-objects.mdx
@@ -0,0 +1,3801 @@
+---
+title: "ZBiotics Custom Objects"
+sidebarTitle: "Custom Objects"
+description: "Inventory of custom BigQuery objects in the ZBiotics data warehouse"
+icon: "database"
+---
+
+[← Back to ZBiotics](/tenants/zbiotics) | [Open sm-zbiotics in BigQuery →](https://console.cloud.google.com/bigquery?project=sm-zbiotics)
+
+
+# Custom Objects Inventory
+
+This page documents active custom BigQuery tables and views (those queried at least once in the past 180 days) created specifically for ZBiotics, separate from the standard SourceMedium data models.
+
+
+**Last Updated (snapshot_at):** `2026-02-03 19:47 EST`
+**Data Source:** Auto-generated from `sm_metadata.dim_tenant_custom_objects`. Only objects with at least 1 query in the past 180 days are included.
+
+
+## Summary
+
+| Dataset | Object Count | Total Jobs (180d) |
+|---------|--------------|-------------------|
+| [`dbt`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2sdbt) | 49 | 87,814 |
+| [`hubspot`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2shubspot) | 49 | 60,159 |
+| [`cin7core`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2scin7core) | 30 | 34,737 |
+| [`twilio`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2stwilio) | 13 | 23,583 |
+| [`pipe17`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2spipe17) | 22 | 21,139 |
+| [`zb_sources`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2szb_sources) | 12 | 15,760 |
+| [`zb_transforms`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2szb_transforms) | 9 | 12,955 |
+| [`dbt_smathur`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2sdbt_smathur) | 42 | 7,338 |
+| [`fivetran_metadata`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2sfivetran_metadata) | 13 | 6,364 |
+| [`skio`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2sskio) | 4 | 5,485 |
+| [`twilio_twilio_source`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2stwilio_twilio_source) | 4 | 2,800 |
+| [`twilio_twilio`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2stwilio_twilio) | 1 | 2,100 |
+| [`dbt_jkeane`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2sdbt_jkeane) | 33 | 1,872 |
+| [`sm_sources`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2ssm_sources) | 2 | 1,822 |
+| [`zb_static`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2szb_static) | 1 | 1 |
+
+---
+
+## Objects by Dataset
+
+### dbt
+
+
+**Type:** BASE TABLE | **Queries (180d):** 28,813
+
+Order-level data Key columns: `sm_order_key, sm_customer_key, source_system, channel, sub_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sorders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 9,775
+
+Order-level data Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sorder_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,258
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, order_id, hubspot_company_id, hubspot_company_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_manual_wholesale_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_manual_wholesale_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,038
+
+Custom data Key columns: `sm_order_key, fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sfulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,439
+
+Marketing/advertising data Key columns: `marketing_month, acquisition_spend, core_acquisition_spend, brand_spend, retention_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3smarketing_spend)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.marketing_spend` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,913
+
+Intermediate transformation Key columns: `door_id, hubspot_company_id, hubspot_company_name, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_wholesale_doors)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_wholesale_doors` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,801
+
+Intermediate transformation Key columns: `sticker_email, sticker_response_date, customer_id, first_shopify_order_created_at, customer_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_sticker_matching)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_sticker_matching` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,408
+
+Intermediate transformation Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,401
+
+Customer-level data Key columns: `sm_customer_key, source_system, customer_created_at, cohort, is_retail`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scustomers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,048
+
+Custom data Key columns: `denominator_id, hubspot_retailer_id, hubspot_retailer_name, week_start, doors_this_week`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sretail_velocity_denominator)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.retail_velocity_denominator` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,948
+
+Custom data Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sretailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,941
+
+Intermediate transformation Key columns: `sticker_response_month, downweight, existing_customer_responses, sticker_responses`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_downweights)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_downweights` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,802
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,668
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, external_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_tickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,567
+
+Custom data Key columns: `subscription_id, storefront_user_id, product, cohort_month, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3ssubscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,552
+
+Intermediate transformation Key columns: `subscription_line_id, subscription_id, created_at, updated_at, removed_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_subscription_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_subscription_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,500
+
+Custom data Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, first_agent_response_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3stickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,446
+
+Custom data Key columns: `session_id, latest_timestamp, phone_number, email, source`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3ssurvey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,421
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, customer_email, customer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_wholesale_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_wholesale_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,393
+
+Metrics definitions Key columns: `date_day, timestamp_pt, week_start_saturday, week_start_sunday`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3smetricflow_time_spine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.metricflow_time_spine` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,390
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, is_actionable, og_tag_name, tag_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_ticket_tags)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_ticket_tags` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,164
+
+Intermediate transformation Key columns: `session_id, latest_timestamp, source, pack, phone_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,011
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, order_id, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_sm_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_sm_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 828
+
+Intermediate transformation Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system, sale_order_line_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_manual_wholesale_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_manual_wholesale_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 776
+
+Intermediate transformation Key columns: `subscription_id, created_at, updated_at, paused_at, cancelled_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_subscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 648
+
+Intermediate transformation Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_wholesale_retailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_wholesale_retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 390
+
+Intermediate transformation Key columns: `fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at, shipping_charge`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_fulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 388
+
+Intermediate transformation Key columns: `message_id, ticket_id, nth_ticket_message, message_created_at, message_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_ticket_messages)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_ticket_messages` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 370
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 356
+
+Custom data Key columns: `customer, phone_number, email, survey_date, brand`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sgsh_historical_cartograph_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.gsh_historical_cartograph_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 337
+
+Custom data Key columns: `test_name, test_group_name, order_id, order_name, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sgsh_intelligems_experiments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.gsh_intelligems_experiments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 300
+
+Custom data Key columns: `company_week_sku_key, hubspot_retailer_id, hubspot_retailer_name, channel, sub_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sretail_velocity)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.retail_velocity` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 124
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_sale)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_sale` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 116
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_customer)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_customer` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 116
+
+Order-level data Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number_list`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_ecomm_aggregated_sale_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_ecomm_aggregated_sale_order_line` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 114
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sretail_velocity_numerator)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.retail_velocity_numerator` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 68
+
+Intermediate transformation Key columns: `spine_date, cin7_source_channel, canonical_sku, human_sku, order_date`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_daily_sku_cost)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_daily_sku_cost` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 44
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3shubspot_company)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.hubspot_company` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 43
+
+Intermediate transformation Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_accounting_sales_lines_order_lines_lkup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_accounting_sales_lines_order_lines_lkup` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 43
+
+Intermediate transformation Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sint_accounting_sales_orders_lkup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.int_accounting_sales_orders_lkup` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 16
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3spipe17_fulfillment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.pipe17_fulfillment` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 12
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3spipe17_location)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.pipe17_location` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `quickbooks_month, total_bank_accounts, goods_invoiced_not_received, inventory_finished_goods_deleted, inventory_ingredients_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sgsh_balance_sheet)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.gsh_balance_sheet` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 6
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3shubspot_company_contact)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.hubspot_company_contact` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 5
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_sale_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_sale_order_line` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_wholesale_sale)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_wholesale_sale` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Marketing/advertising data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3sgsh_marketing_spend_monthly)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.gsh_marketing_spend_monthly` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3stwilio_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.twilio_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1
+
+Order-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt!3scin7_wholesale_sale_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt.cin7_wholesale_sale_order_line` LIMIT 10;
+```
+
+
+
+### hubspot
+
+
+**Type:** BASE TABLE | **Queries (180d):** 4,615
+
+Custom data Key columns: `property_hs_avatar_filemanager_key, property_carried_skus, property_num_associated_contacts, property_social_media, property_hs_time_in_lead`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scompany)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.company` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,642
+
+Custom data Key columns: `contact_id, category, company_id, type_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_company)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_company` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,442
+
+Custom data Key columns: `property_hs_is_unworked, property_hs_first_outreach_date, property_notes_last_updated, property_email, property_hs_pipeline`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,309
+
+Custom data Key columns: `name, list_version, processing_status, created_by_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_list)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_list` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,307
+
+Custom data Key columns: `email, first_name, last_name, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3susers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.users` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,307
+
+Custom data Key columns: `category, name, label, from_object_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sassociation_type)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.association_type` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,599
+
+Monthly aggregation Key columns: `breakdown, date, desktop, direct_traffic, email_marketing`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssessions_analytics_monthly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sessions_analytics_monthly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Weekly aggregation Key columns: `date, contacts, contacts_per_pageview, leads, leads_per_view`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3stotals_analytics_weekly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.totals_analytics_weekly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Monthly aggregation Key columns: `date, contacts, contacts_per_pageview, leads, leads_per_view`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3stotals_analytics_monthly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.totals_analytics_monthly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Monthly aggregation Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sgeolocation_analytics_monthly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.geolocation_analytics_monthly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `date, contacts, contacts_per_pageview, leads, leads_per_view`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3stotals_analytics_daily_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.totals_analytics_daily_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `pipeline_id, label, display_order, created_at, updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sdeal_pipeline)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.deal_pipeline` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `stage_id, pipeline_id, label, display_order, write_permissions`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sdeal_pipeline_stage)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.deal_pipeline_stage` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Weekly aggregation Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sgeolocation_analytics_weekly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.geolocation_analytics_weekly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Weekly aggregation Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssources_analytics_weekly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sources_analytics_weekly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sgeolocation_analytics_daily_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.geolocation_analytics_daily_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Monthly aggregation Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssources_analytics_monthly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sources_analytics_monthly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `guid, portal_id, name, action, method`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sform)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.form` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `breakdown, date, bounce_rate, bounces, contacts`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssources_analytics_daily_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sources_analytics_daily_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `portal_id, name, description, active`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3semail_subscription)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.email_subscription` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `stage_id, pipeline_id, label, display_order, write_permissions`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sticket_pipeline_stage)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.ticket_pipeline_stage` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `owner_id, first_name, last_name, email, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sowner)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.owner` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,597
+
+Custom data Key columns: `pipeline_id, label, display_order, created_at, updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sticket_pipeline)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.ticket_pipeline` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,564
+
+Custom data Key columns: `breakdown, date, desktop, direct_traffic, email_marketing`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssessions_analytics_daily_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sessions_analytics_daily_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,564
+
+Weekly aggregation Key columns: `breakdown, date, desktop, direct_traffic, email_marketing`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssessions_analytics_weekly_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sessions_analytics_weekly_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,051
+
+Marketing/advertising data Key columns: `campaign_id, marketing_email_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3smarketing_email_campaign)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.marketing_email_campaign` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 890
+
+Custom data Key columns: `label, property_id, value, display_order, hidden`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sproperty_option)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.property_option` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 890
+
+Custom data Key columns: `_fivetran_id, hubspot_object, name, label, type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sproperty)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.property` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 889
+
+Custom data Key columns: `breakdown, desktop, direct_traffic, email_marketing, mobile`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssessions_analytics_overall_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sessions_analytics_overall_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 887
+
+Custom data Key columns: `breakdown, utm_type, bounce_rate, bounces, new_visitor_session_rate`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sutm_analytics_overall_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.utm_analytics_overall_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 887
+
+Custom data Key columns: `breakdown, bounce_rate, bounces, contacts, contacts_per_pageview`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sgeolocation_analytics_overall_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.geolocation_analytics_overall_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 887
+
+Custom data Key columns: `breakdown, bounce_rate, bounces, contacts, contacts_per_pageview`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssources_analytics_overall_report)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.sources_analytics_overall_report` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 800
+
+Custom data Key columns: `company_id, name, timestamp, value, source_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scompany_property_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.company_property_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 772
+
+Custom data Key columns: `contact_id, name, timestamp, value, source_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_property_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_property_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 752
+
+Custom data Key columns: `from_company_id, category, to_company_id, type_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scompany_company)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.company_company` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 602
+
+Custom data Key columns: `engagement_id, engagement_type, category, company_id, type_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_company)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_company` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 589
+
+Custom data Key columns: `engagement_id, engagement_type, name, timestamp, value`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_property_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_property_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 550
+
+Custom data Key columns: `from_contact_id, category, to_contact_id, type_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_contact)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_contact` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 488
+
+Custom data Key columns: `type, portal_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 434
+
+Marketing/advertising data Key columns: `subscription, ab, ab_hours_to_wait, ab_variation`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3smarketing_email)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.marketing_email` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 413
+
+Custom data Key columns: `_fivetran_deleted, type, property_hs_lastmodifieddate, property_hs_meeting_outcome`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_meeting)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_meeting` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 372
+
+Custom data Key columns: `contact_id, form_id, timestamp, portal_id, page_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_form_submission)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_form_submission` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 289
+
+Custom data Key columns: `property_hs_page_id, property_hs_is_amp, property_hs_canonical_url, property_hs_user_agent, property_hs_device_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sevent)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.event` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 232
+
+Custom data Key columns: `engagement_id, engagement_type, category, contact_id, type_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_contact)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_contact` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 170
+
+Custom data Key columns: `property_hs_email_message_id, property_hs_email_to_lastname, property_hs_email_direction, property_hs_email_tracker_key, property_hs_not_tracking_opens_or_clicks`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_email)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_email` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 150
+
+Custom data Key columns: `conversion_id, form_id, field_name, field_value, submitted_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3ssubmission_response)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.submission_response` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 129
+
+Custom data Key columns: `engagement_id, type, _fivetran_deleted, property_hs_task_relative_reminders`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_task)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_task` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 112
+
+Custom data Key columns: `contact_id, contact_list_id, _fivetran_deleted, added_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3scontact_list_member)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.contact_list_member` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 23
+
+Custom data Key columns: `_fivetran_deleted, type, property_hs_lastmodifieddate, property_hs_body_preview_is_truncated`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2shubspot!3sengagement_note)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.hubspot.engagement_note` LIMIT 10;
+```
+
+
+
+### cin7core
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,440
+
+Custom data Key columns: `manual_journal_line, quote_prepayment, _fivetran_deleted, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,604
+
+Customer-level data Key columns: `_fivetran_deleted, revenue_account, discount`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3scustomer)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.customer` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,310
+
+Order-level data Key columns: `sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_order_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,679
+
+Custom data Key columns: `fulfillment_number, sale_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_fullfillment_ship_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_fullfillment_ship_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,677
+
+Custom data Key columns: `fulfillment_number, sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_fullfillment_pack_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_fullfillment_pack_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,595
+
+Custom data Key columns: `fulfillment_number, sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_fullfillment_pick_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_fullfillment_pick_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,321
+
+Custom data Key columns: `sale_credit_note_task_id, sale_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_credit_note_refund)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_credit_note_refund` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,308
+
+Custom data Key columns: `sale_credit_note_task_id, sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_credit_note_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_credit_note_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,215
+
+Product/SKU-level data Key columns: `suppliers, _fivetran_deleted, category_id, cogs_account`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,213
+
+Custom data Key columns: `sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_inventory_movement)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_inventory_movement` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,195
+
+Product/SKU-level data Key columns: `product_id, _fivetran_deleted, content_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct_attachment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product_attachment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,177
+
+Custom data Key columns: `product_id, component_product_id, _fivetran_deleted, expense_account`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sbill_of_material_service)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.bill_of_material_service` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,167
+
+Product/SKU-level data Key columns: `product_id, component_product_id, _fivetran_deleted, quantity`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sbill_of_material_product)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.bill_of_material_product` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,129
+
+Custom data Key columns: `sale_id, transaction_id, _fivetran_deleted, task_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_transaction)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_transaction` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,120
+
+Custom data Key columns: `sale_id, sale_invoice_task_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_invoice_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_invoice_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,118
+
+Custom data Key columns: `sale_id, task_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_credit_note)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_credit_note` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,114
+
+Custom data Key columns: `sale_id, fulfillment_number, task_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_fullfillment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_fullfillment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,113
+
+Custom data Key columns: `sale_id, task_id, payment, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_invoice)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_invoice` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,023
+
+Custom data Key columns: `sale_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_attachment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_attachment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 990
+
+Custom data Key columns: `sale_credit_note_task_id, sale_id, index, _fivetran_deleted, product_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_credit_note_restock)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_credit_note_restock` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 949
+
+Product/SKU-level data Key columns: `product_id, index, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct_movement)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product_movement` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 889
+
+Product/SKU-level data Key columns: `tier_number, _fivetran_deleted, product_id, markup_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct_markup_price)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product_markup_price` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 560
+
+Customer-level data Key columns: `customer_id, _fivetran_deleted, include_in_email`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3scustomer_contacts)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.customer_contacts` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 538
+
+Marketing/advertising data Key columns: `_fivetran_id, _fivetran_deleted, sale_id, sale_invoice_task_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_invoice_additional_charge)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_invoice_additional_charge` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 537
+
+Order-level data Key columns: `_fivetran_id, _fivetran_deleted, sale_id, total`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_order_additional_charge)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_order_additional_charge` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 463
+
+Marketing/advertising data Key columns: `_fivetran_id, _fivetran_deleted, sale_credit_note_task_id, sale_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3ssale_credit_note_additional_charge)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.sale_credit_note_additional_charge` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 424
+
+Customer-level data Key columns: `customer_id, _fivetran_deleted, line_1`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3scustomer_address)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.customer_address` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 404
+
+Customer-level data Key columns: `customer_id, product_id, _fivetran_deleted, price`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3scustomer_product_price)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.customer_product_price` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 344
+
+Product/SKU-level data Key columns: `_fivetran_id, _fivetran_deleted, customer_id, price`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct_custom_price)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product_custom_price` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 121
+
+Product/SKU-level data Key columns: `product_id, _fivetran_deleted, in_transit, batch`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2scin7core!3sproduct_availability)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.cin7core.product_availability` LIMIT 10;
+```
+
+
+
+### twilio
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,770
+
+Custom data from Twilio Key columns: `account_id, category, end_date, start_date, description`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3susage_record)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.usage_record` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,039
+
+Custom data from Twilio Key columns: `updated_at, status, friendly_name, type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3saccount_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.account_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,014
+
+Custom data from Twilio Key columns: `friendly_name, sticky_sender, mms_converter, smart_encoding`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3smessaging_service)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.messaging_service` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,295
+
+Custom data from Twilio Key columns: `role_id, permission, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3srole_permission)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.role_permission` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,278
+
+Custom data from Twilio Key columns: `date_sent, direction, error_code, error_message`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3smessage)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.message` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,639
+
+Custom data from Twilio Key columns: `updated_at, friendly_name, status, version`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3sflow_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.flow_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,589
+
+Custom data from Twilio Key columns: `friendly_name, _fivetran_deleted, account_id, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3sservice)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.service` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,589
+
+Custom data from Twilio Key columns: `friendly_name, type, _fivetran_deleted, account_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3srole)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.role` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 908
+
+Custom data from Twilio Key columns: `friendly_name, phone_number, updated_at, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3soutgoing_caller_id)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.outgoing_caller_id` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 908
+
+Custom data from Twilio Key columns: `capabilities_mms, capabilities_sms, capabilities_voice, address_requirements`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3sincoming_phone_number)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.incoming_phone_number` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 908
+
+Marketing/advertising data from Twilio Key columns: `city, customer_name, emergency_enabled, friendly_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3saddress)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.address` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 823
+
+Custom data from Twilio Key columns: `context, status, contact_channel_address, updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3sexecution)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.execution` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 823
+
+Custom data from Twilio Key columns: `context, name, transitioned_from, transitioned_to`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio!3sexecution_step)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio.execution_step` LIMIT 10;
+```
+
+
+
+### pipe17
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,429
+
+Custom data Key columns: `quantity, bundle_quantity_partial, bundle_quantity, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sfulfillment_line_item)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.fulfillment_line_item` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,330
+
+Order-level data Key columns: `orders_id, line_item_id, type, reference, label`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sorder_discount)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.order_discount` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,889
+
+Custom data Key columns: `shipping_class, actual_ship_date, external_fulfillment_id, external_order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sfulfillment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.fulfillment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,628
+
+Order-level data Key columns: `custom_var_auto_merge_billing_sub_id, orders_id, item_discount, requires_shipping, custom_var_ig_test_group`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sorder_line_item)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.order_line_item` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,628
+
+Custom data Key columns: `custom_var_auto_merge_billing_sub_id, custom_var_ig_test_group, _fivetran_deleted, custom_var_is_gift_subscription, custom_var_source`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sshipment_line_item)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.shipment_line_item` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,623
+
+Order-level data Key columns: `orders_id, index, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sorder_tag)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.order_tag` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,621
+
+Order-level data Key columns: `orders_id, index, conversion, currency, method`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sorder_payment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.order_payment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,621
+
+Custom data Key columns: `shipment_id, index, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sshipment_tag)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.shipment_tag` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,484
+
+Order-level data Key columns: `sub_total_price, require_shipping_labels, shipping_class, currency`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sorders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,482
+
+Custom data Key columns: `order_type, shipping_class, external_reference_url, order_create_time`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sshipment)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.shipment` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 928
+
+Custom data Key columns: `email, name, updated_at, exclude_from_totals`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3slocation)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.location` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 913
+
+Custom data Key columns: `committed_future, integration_id, unavailable, available, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sinventory)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.inventory` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 249
+
+Product/SKU-level data Key columns: `product_id, index, tags, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct_tag)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product_tag` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 241
+
+Product/SKU-level data Key columns: `product_id, index, name, value, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct_variant_option)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product_variant_option` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 226
+
+Product/SKU-level data Key columns: `product_id, type, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct_type)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product_type` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 226
+
+Product/SKU-level data Key columns: `product_id, index, buffer_inventory, name, updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct_published)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product_published` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 226
+
+Product/SKU-level data Key columns: `product_id, index, name, value, currency`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct_price)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product_price` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 195
+
+Custom data Key columns: `rule, ptype, event, updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sinventory_rule)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.inventory_rule` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 157
+
+Product/SKU-level data Key columns: `cost_currency, part_id, width, sku`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sproduct)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.product` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 18
+
+Custom data Key columns: `is_default, is_passthrough, source_type, source_integration_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sshipping_method)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.shipping_method` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 18
+
+Custom data Key columns: `method_id, shipping_method_id, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3sshipping_method_mapped_method)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.shipping_method_mapped_method` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 7
+
+Custom data Key columns: `location_id, index, integration_id, location_value, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2spipe17!3slocation_external_system)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.pipe17.location_external_system` LIMIT 10;
+```
+
+
+
+### zb_sources
+
+
+**Type:** EXTERNAL | **Queries (180d):** 5,769
+
+Marketing/advertising data Key columns: `month, sheet_ignore, acquisition_spend, brand_spend, retention_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3smarketing_spend_tracker)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.marketing_spend_tracker` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 2,665
+
+Raw/native source data from Amazon Key columns: `customer, sticker_number, sticker_email, sticker_response_date, brand`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3sraw_amazon_sticker_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.raw_amazon_sticker_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,167
+
+Marketing/advertising data Key columns: `month, acquisition_spend, core_acquisition_spend, brand_spend, retention_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3smarketing_spend_monthly)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.marketing_spend_monthly` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 1,624
+
+Product/SKU-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3ssku_lookup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.sku_lookup` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 775
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3smcf_estimated_fees)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.mcf_estimated_fees` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 460
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3shistorical_cartograph_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.historical_cartograph_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 455
+
+Custom data Key columns: `print_name, full_name, email`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3szb_employees)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.zb_employees` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 451
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3sholidays)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.holidays` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 451
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3sintelligems_experiment_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.intelligems_experiment_data` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 450
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3squickbooks_balance_sheet)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.quickbooks_balance_sheet` LIMIT 10;
+```
+
+
+
+**Type:** EXTERNAL | **Queries (180d):** 450
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3squickbooks_profit_loss)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.quickbooks_profit_loss` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 43
+
+Custom data Key columns: `zip_code, latitude, longitude`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_sources!3szip_code_coords)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_sources.zip_code_coords` LIMIT 10;
+```
+
+
+
+### zb_transforms
+
+
+**Type:** BASE TABLE | **Queries (180d):** 3,242
+
+Aggregated summary Key columns: `rpt_date, sm_channel, downweight, order_net_revenue, new_customer_order_net_revenue`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3srpt_executive_summary_daily)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.rpt_executive_summary_daily` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,644
+
+Fact table from Amazon Key columns: `sticker_email, sticker_response_date, customer_id, first_shopify_order_created_at, customer_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3sfct_amazon_sticker_response_matches)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.fct_amazon_sticker_response_matches` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,168
+
+Fact table from Amazon Key columns: `sticker_response_month, downweight, existing_customer_responses, sticker_responses`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3sfct_amazon_new_downweights)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.fct_amazon_new_downweights` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,168
+
+Denormalized "One Big Table" view Key columns: `sm_store_id, sm_order_key, sm_customer_key, source_system, order_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3sobt_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.obt_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,167
+
+Dimension table Key columns: `order_line_id, sm_order_key, sm_order_line_key, sm_product_key, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3sdim_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.dim_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 484
+
+Aggregated summary Key columns: `rpt_month, total_net_revenue, total_order_count, total_adj_new_order_count, total_adj_existing_order_count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3srpt_executive_summary_monthly)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.rpt_executive_summary_monthly` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 36
+
+Order-level data Key columns: `sale_id, source_channel, order_date, order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3scogs_per_order)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.cogs_per_order` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 26
+
+Order-level data Key columns: `sm_order_key, source_system, order_name, ordered_at, sm_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3scogs_per_order_db)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.cogs_per_order_db` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 20
+
+Order-level data Key columns: `sale_id, source_channel, order_date, order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_transforms!3sorder_number_map)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_transforms.order_number_map` LIMIT 10;
+```
+
+
+
+### dbt_smathur
+
+
+**Type:** BASE TABLE | **Queries (180d):** 744
+
+Order-level data Key columns: `sm_order_key, sm_customer_key, source_system, channel, sub_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sorders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 598
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, order_id, hubspot_company_id, hubspot_company_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_manual_wholesale_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_manual_wholesale_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 461
+
+Intermediate transformation Key columns: `subscription_line_id, subscription_id, created_at, updated_at, removed_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_subscription_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_subscription_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 461
+
+Intermediate transformation Key columns: `subscription_id, created_at, updated_at, paused_at, cancelled_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_subscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 390
+
+Order-level data Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sorder_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 376
+
+Intermediate transformation Key columns: `door_id, hubspot_company_id, hubspot_company_name, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_wholesale_doors)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_wholesale_doors` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 362
+
+Intermediate transformation Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 361
+
+Custom data Key columns: `denominator_id, hubspot_retailer_id, hubspot_retailer_name, week_start, doors_this_week`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sretail_velocity_denominator)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.retail_velocity_denominator` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 351
+
+Intermediate transformation Key columns: `sticker_email, sticker_response_date, customer_id, first_shopify_order_created_at, customer_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_sticker_matching)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_sticker_matching` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 297
+
+Intermediate transformation Key columns: `sticker_response_month, downweight, existing_customer_responses, sticker_responses`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_downweights)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_downweights` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 278
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, order_id, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_sm_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_sm_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 266
+
+Custom data Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sretailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 213
+
+Metrics definitions Key columns: `date_day, timestamp_pt, week_start_saturday, week_start_sunday`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3smetricflow_time_spine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.metricflow_time_spine` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 197
+
+Marketing/advertising data Key columns: `marketing_month, acquisition_spend, core_acquisition_spend, brand_spend, retention_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3smarketing_spend)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.marketing_spend` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 191
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, customer_email, customer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_wholesale_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_wholesale_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 185
+
+Custom data Key columns: `subscription_id, storefront_user_id, product, cohort_month, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3ssubscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 167
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 150
+
+Custom data Key columns: `hubspot_retailer_id, hubspot_retailer_name, week_start, units_this_week, doors_this_week`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sretail_velocity)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.retail_velocity` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 147
+
+Customer-level data Key columns: `sm_customer_key, source_system, customer_created_at, cohort, is_retail`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3scustomers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 147
+
+Intermediate transformation Key columns: `session_id, latest_timestamp, source, pack, phone_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 141
+
+Custom data Key columns: `session_id, latest_timestamp, phone_number, email, source`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3ssurvey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 124
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, external_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_tickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 120
+
+Custom data Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, first_agent_response_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3stickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 112
+
+Intermediate transformation Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system, sale_order_line_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_manual_wholesale_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_manual_wholesale_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 106
+
+Intermediate transformation Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_wholesale_retailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_wholesale_retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 55
+
+Order-level data Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number_list`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3scin7_ecomm_aggregated_sale_order_line)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.cin7_ecomm_aggregated_sale_order_line` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 55
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 43
+
+Custom data Key columns: `customer, phone_number, email, survey_date, brand`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sgsh_historical_cartograph_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.gsh_historical_cartograph_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 41
+
+Intermediate transformation Key columns: `spine_date, cin7_source_channel, canonical_sku, human_sku, order_date`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_daily_sku_cost)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_daily_sku_cost` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 34
+
+Intermediate transformation Key columns: `fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at, shipping_charge`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_fulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 31
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, is_actionable, og_tag_name, tag_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_ticket_tags)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_ticket_tags` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 31
+
+Intermediate transformation Key columns: `message_id, ticket_id, nth_ticket_message, message_created_at, message_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_ticket_messages)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_ticket_messages` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 25
+
+Custom data Key columns: `sm_order_key, fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sfulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 15
+
+Intermediate transformation Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_accounting_sales_orders_lkup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_accounting_sales_orders_lkup` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 14
+
+Intermediate transformation Key columns: `cin7_sale_id, cin7_source_channel, order_date, cin7_so_order_number, source_order_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_accounting_sales_lines_order_lines_lkup)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_accounting_sales_lines_order_lines_lkup` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 12
+
+Intermediate transformation Key columns: `cin7_source_channel, source_sku, human_sku, canonical_sku, product`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_sku_cost_scd)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_sku_cost_scd` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Intermediate transformation Key columns: `cin7_source_channel, order_date, source_sku, human_sku, canonical_sku`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sint_daily_source_sku_cost_observations)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.int_daily_source_sku_cost_observations` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 11
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sretail_velocity_numerator)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.retail_velocity_numerator` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 7
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3shubspot_company_contact)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.hubspot_company_contact` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 5
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3shubspot_company)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.hubspot_company` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 2
+
+Denormalized "One Big Table" view
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3sobt_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.obt_customers` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1
+
+Customer-level data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_smathur!3scin7_customer)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_smathur.cin7_customer` LIMIT 10;
+```
+
+
+
+### fivetran_metadata
+
+
+**Type:** BASE TABLE | **Queries (180d):** 708
+
+Custom data Key columns: `role_id, permission, _fivetran_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3srole_permission)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.role_permission` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 708
+
+Custom data Key columns: `role_id, team_id, user_id, account_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sresource_membership)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.resource_membership` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 701
+
+Custom data Key columns: `destination_id, job_id, measured_date, project_type, free_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3stransformation_runs)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.transformation_runs` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 688
+
+Custom data Key columns: `connection_name, destination_id, measured_date, schema_name, sync_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sincremental_mar)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.incremental_mar` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 535
+
+Custom data Key columns: `given_name, family_name, email, email_disabled`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3suser)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.user` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 535
+
+Custom data Key columns: `time_stamp, connector_id, connection_id, event`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3slog)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.log` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 535
+
+Custom data Key columns: `connection_id, connecting_user_id, connector_type_id, connection_name, signed_up`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sconnection)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.connection` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 531
+
+Custom data Key columns: `name, description, account_id, connector_types`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3srole)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.role` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 356
+
+Custom data Key columns: `name, account_id, created_at, region`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sdestination)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.destination` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 356
+
+Custom data Key columns: `official_connector_name, type, availability, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sconnector_type)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.connector_type` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 356
+
+Custom data Key columns: `name, created_at, status, country`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3saccount)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.account` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 190
+
+Custom data Key columns: `measured_month, destination_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3susage_cost)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.usage_cost` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 165
+
+Custom data Key columns: `connector_id, connecting_user_id, connector_type_id, connector_name, signed_up`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sfivetran_metadata!3sconnector)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.fivetran_metadata.connector` LIMIT 10;
+```
+
+
+
+### skio
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,312
+
+Custom data Key columns: `createdAt, updatedAt, cognitoUsername, email`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sskio!3sStorefrontUser)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.skio.StorefrontUser` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1,357
+
+Product/SKU-level data Key columns: `createdAt, updatedAt, price, title`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sskio!3sProductVariant)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.skio.ProductVariant` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 910
+
+Custom data Key columns: `createdAt, updatedAt, billingPolicyId, deliveryPolicyId`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sskio!3sSubscription)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.skio.Subscription` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 906
+
+Custom data Key columns: `updatedAt, createdAt, subscriptionId, priceWithoutDiscount`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sskio!3sSubscriptionLine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.skio.SubscriptionLine` LIMIT 10;
+```
+
+
+
+### twilio_twilio_source
+
+
+**Type:** BASE TABLE | **Queries (180d):** 700
+
+Staging data from Twilio Key columns: `_fivetran_deleted, account_id, area_code_geomatch, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio_twilio_source!3sstg_twilio__messaging_service)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio_twilio_source.stg_twilio__messaging_service` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 700
+
+Staging data from Twilio Key columns: `account_id, as_of, category, count`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio_twilio_source!3sstg_twilio__usage_record)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio_twilio_source.stg_twilio__usage_record` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 700
+
+Staging data from Twilio Key columns: `created_at, friendly_name, account_id, owner_account_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio_twilio_source!3sstg_twilio__account_history)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio_twilio_source.stg_twilio__account_history` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 700
+
+Staging data from Twilio Key columns: `account_id, body, created_at, timestamp_sent`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio_twilio_source!3sstg_twilio__message)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio_twilio_source.stg_twilio__message` LIMIT 10;
+```
+
+
+
+### twilio_twilio
+
+
+**Type:** BASE TABLE | **Queries (180d):** 2,100
+
+Intermediate transformation from Twilio Key columns: `account_id, body, num_characters, body_no_spaces, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2stwilio_twilio!3sint_twilio__messages)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.twilio_twilio.int_twilio__messages` LIMIT 10;
+```
+
+
+
+### dbt_jkeane
+
+
+**Type:** BASE TABLE | **Queries (180d):** 194
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, order_id, hubspot_company_id, hubspot_company_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_manual_wholesale_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_manual_wholesale_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 126
+
+Intermediate transformation Key columns: `sticker_email, sticker_response_date, customer_id, first_shopify_order_created_at, customer_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_sticker_matching)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_sticker_matching` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 108
+
+Intermediate transformation Key columns: `door_id, hubspot_company_id, hubspot_company_name, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_wholesale_doors)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_wholesale_doors` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 107
+
+Intermediate transformation Key columns: `sm_store_id, sm_order_line_key, sm_order_key, sm_customer_key, sm_product_variant_key`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 105
+
+Marketing/advertising data Key columns: `marketing_month, acquisition_spend, core_acquisition_spend, brand_spend, retention_spend`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3smarketing_spend)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.marketing_spend` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 100
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, external_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_tickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 91
+
+Intermediate transformation Key columns: `sticker_response_month, downweight, existing_customer_responses, sticker_responses`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_downweights)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_downweights` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 88
+
+Intermediate transformation Key columns: `subscription_line_id, subscription_id, created_at, updated_at, removed_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_subscription_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_subscription_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 68
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, customer_email, customer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_wholesale_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_wholesale_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 68
+
+Custom data Key columns: `subscription_id, storefront_user_id, product, cohort_month, created_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3ssubscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 66
+
+Intermediate transformation Key columns: `session_id, latest_timestamp, source, pack, phone_number`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 66
+
+Custom data Key columns: `ticket_id, ticket_created_at, ticket_closed_at, ticket_updated_at, first_agent_response_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3stickets)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.tickets` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 65
+
+Order-level data Key columns: `sm_order_key, sm_customer_key, hubspot_company_id, hubspot_company_name, hubspot_retailer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sorders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 60
+
+Custom data Key columns: `session_id, latest_timestamp, phone_number, email, source`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3ssurvey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 54
+
+Custom data Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sretailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 52
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 44
+
+Intermediate transformation Key columns: `subscription_id, created_at, updated_at, paused_at, cancelled_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_subscriptions)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_subscriptions` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 44
+
+Intermediate transformation Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system, sale_order_line_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_manual_wholesale_order_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_manual_wholesale_order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 42
+
+Custom data Key columns: `denominator_id, hubspot_retailer_id, hubspot_retailer_name, week_start, doors_this_week`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sretail_velocity_denominator)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.retail_velocity_denominator` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 40
+
+Customer-level data Key columns: `sm_customer_key, source_system, customer_id, customer_created_at, cohort`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3scustomers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 39
+
+Custom data Key columns: `company_week_sku_key, hubspot_retailer_id, hubspot_retailer_name, channel, sub_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sretail_velocity)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.retail_velocity` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 31
+
+Order-level data Key columns: `sm_order_line_key, sm_order_key, sm_customer_key, source_system`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sorder_lines)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.order_lines` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 29
+
+Custom data Key columns: `customer, phone_number, email, survey_date, brand`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sgsh_historical_cartograph_survey_responses)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.gsh_historical_cartograph_survey_responses` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 29
+
+Intermediate transformation Key columns: `fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at, shipping_charge`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_fulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 27
+
+Intermediate transformation Key columns: `hubspot_retailer_id, hubspot_retailer_name, source_system, order_attribution_types, wholesale_channels`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_wholesale_retailers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_wholesale_retailers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 26
+
+Intermediate transformation Key columns: `ticket_id, ticket_created_at, is_actionable, og_tag_name, tag_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_ticket_tags)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_ticket_tags` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 23
+
+Intermediate transformation Key columns: `sm_order_key, sm_customer_key, source_system, order_id, customer_id`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_sm_orders)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_sm_orders` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 22
+
+Intermediate transformation Key columns: `message_id, ticket_id, nth_ticket_message, message_created_at, message_type`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_ticket_messages)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_ticket_messages` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 18
+
+Intermediate transformation Key columns: `sm_customer_key, source_system, customer_id, hubspot_retailer_id, hubspot_retailer_name`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sint_customers)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.int_customers` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 17
+
+Metrics definitions Key columns: `date_day, timestamp_pt, week_start_saturday, week_start_sunday`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3smetricflow_time_spine)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.metricflow_time_spine` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `sm_order_key, fulfillment_id, shopify_order_id, fulfillment_created_at, fulfillment_updated_at`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sfulfillments)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.fulfillments` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 11
+
+Custom data Key columns: `quickbooks_month, total_bank_accounts, goods_invoiced_not_received, inventory_finished_goods_deleted, inventory_ingredients_deleted`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sgsh_balance_sheet)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.gsh_balance_sheet` LIMIT 10;
+```
+
+
+
+**Type:** VIEW | **Queries (180d):** 1
+
+Custom data
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2sdbt_jkeane!3sgsh_mcf_estimated_fees)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.dbt_jkeane.gsh_mcf_estimated_fees` LIMIT 10;
+```
+
+
+
+### sm_sources
+
+
+**Type:** BASE TABLE | **Queries (180d):** 911
+
+Custom data Key columns: `_airbyte_raw_id, _airbyte_extracted_at, _airbyte_generation_id, uri`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2ssm_sources!3szbiotics_gorgias_tickets_raw)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.sm_sources.zbiotics_gorgias_tickets_raw` LIMIT 10;
+```
+
+
+
+**Type:** BASE TABLE | **Queries (180d):** 911
+
+Custom data Key columns: `uri, via, public, channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2ssm_sources!3szbiotics_ticket_message_data)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.sm_sources.zbiotics_ticket_message_data` LIMIT 10;
+```
+
+
+
+### zb_static
+
+
+**Type:** BASE TABLE | **Queries (180d):** 1
+
+Order-level data Key columns: `sm_order_key, sm_customer_key, source_system, channel, sub_channel`.
+
+[Open in BigQuery Console →](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m5!1m4!4m3!1ssm-zbiotics!2szb_static!3sjan26_orders_asof_20260202)
+
+```sql
+-- Preview data
+SELECT * FROM `sm-zbiotics.zb_static.jan26_orders_asof_20260202` LIMIT 10;
+```
+
+
+
+---
+
+## Your Data Warehouse
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `sm-zbiotics` |
+| **Standard Dataset** | `sm_transformed_v2` |
+| **Tenant ID** | [`zbiotics`](https://console.cloud.google.com/bigquery?project=sm-zbiotics&ws=!1m4!1m3!3m2!1ssm-zbiotics!2szbiotics)
+
+---
+
+## Notes
+
+- **Usage counts** reflect BigQuery job executions, including scheduled queries, dashboard refreshes, and ad-hoc queries.
+- Objects with low usage may be candidates for cleanup.
+- Click "Open in BigQuery Console" to view the table schema and run queries.
+
+
+For questions about these custom objects or to request modifications, please contact your SourceMedium representative.
+
diff --git a/tests/pytest.ini b/tests/pytest.ini
new file mode 100644
index 0000000..67a468c
--- /dev/null
+++ b/tests/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+markers =
+ live: marks tests that hit the live site (may be slow)
diff --git a/tests/requirements.txt b/tests/requirements.txt
new file mode 100644
index 0000000..bacf455
--- /dev/null
+++ b/tests/requirements.txt
@@ -0,0 +1,2 @@
+pytest>=7.0.0
+requests>=2.28.0
diff --git a/tests/test_live_site.py b/tests/test_live_site.py
new file mode 100644
index 0000000..1a808d3
--- /dev/null
+++ b/tests/test_live_site.py
@@ -0,0 +1,586 @@
+#!/usr/bin/env python3
+"""
+Post-deployment validation tests for SourceMedium documentation site.
+
+This test suite validates that:
+1. All navigation links in docs.json resolve to live pages
+2. Internal links within pages work correctly
+3. Key pages load with expected content
+4. No 404s or server errors
+
+Usage:
+ # Run all tests
+ pytest tests/test_live_site.py -v
+
+ # By default, live tests are excluded (see tests/pytest.ini)
+ # Run live tests explicitly:
+ pytest tests/test_live_site.py -v -m live
+
+ # Run specific test category
+ pytest tests/test_live_site.py -v -k "navigation"
+
+ # Run against staging (default is production)
+ DOCS_BASE_URL=https://staging.docs.sourcemedium.com pytest tests/test_live_site.py -v
+
+Requirements:
+ pip install pytest requests
+"""
+
+import json
+import os
+import re
+import subprocess
+from pathlib import Path
+from urllib.parse import urljoin
+from concurrent.futures import ThreadPoolExecutor, as_completed
+
+import pytest
+import requests
+
+# Configuration
+BASE_URL = os.environ.get("DOCS_BASE_URL", "https://docs.sourcemedium.com").rstrip("/")
+TIMEOUT = float(os.environ.get("DOCS_TIMEOUT", "10"))
+MAX_WORKERS = int(os.environ.get("DOCS_MAX_WORKERS", "8"))
+FAIL_ON_REDIRECT_LOOPS = os.environ.get("DOCS_FAIL_ON_REDIRECT_LOOPS", "0") == "1"
+VERIFY_GIT_SHA = os.environ.get("DOCS_VERIFY_GIT_SHA", "0") == "1"
+REPO_ROOT = Path(__file__).parent.parent
+
+
+@pytest.fixture(scope="session")
+def http_session() -> requests.Session:
+ session = requests.Session()
+ session.headers.update(
+ {
+ "User-Agent": "sourcemedium-docs-live-tests/1.0 (+https://docs.sourcemedium.com)",
+ }
+ )
+
+ try:
+ from requests.adapters import HTTPAdapter
+ from urllib3.util.retry import Retry
+
+ retry = Retry(
+ total=3,
+ connect=3,
+ read=3,
+ status=3,
+ backoff_factor=0.4,
+ status_forcelist=(429, 500, 502, 503, 504),
+ allowed_methods=frozenset(["GET", "HEAD"]),
+ raise_on_status=False,
+ )
+ adapter = HTTPAdapter(max_retries=retry)
+ session.mount("https://", adapter)
+ session.mount("http://", adapter)
+ except Exception:
+ # Keep a plain session if retry wiring isn't available.
+ pass
+
+ return session
+
+
+def normalize_route(ref: str) -> str:
+ """
+ Normalize a docs route/path for consistent comparisons.
+
+ - Ensure leading slash
+ - Remove query + fragment
+ - Remove trailing slash (except root)
+ """
+ clean = ref.strip()
+ if not clean:
+ return clean
+ clean = clean.split("#", 1)[0].split("?", 1)[0]
+ if not clean.startswith("/"):
+ clean = "/" + clean
+ if clean != "/":
+ clean = clean.rstrip("/")
+ return clean
+
+
+def strip_fenced_code_blocks(content: str) -> str:
+ # Remove triple-backtick fenced blocks to avoid false-positive links inside examples.
+ return re.sub(r"```.*?```", "", content, flags=re.DOTALL)
+
+
+def is_asset_path(path: str) -> bool:
+ # Skip paths that point to static assets, not documentation pages.
+ asset_prefixes = ("/images/", "/logo/", "/favicon.", "/snippets/")
+ if path.startswith(asset_prefixes):
+ return True
+ # If it looks like a direct file link (has an extension), treat as asset.
+ return bool(re.search(r"/[^/]+\.[a-zA-Z0-9]{2,5}$", path))
+
+
+def extract_vercel_deployment_id(response: requests.Response) -> str | None:
+ """
+ Mintlify sites are typically hosted on Vercel and often expose a Vercel deployment
+ identifier via response headers.
+
+ We prefer the final response, but some deployments only include the header on
+ a redirect response in the chain.
+ """
+ header_keys = ("x-served-version", "x-version")
+ for key in header_keys:
+ value = response.headers.get(key)
+ if value:
+ return value
+ for prior in reversed(response.history or []):
+ for key in header_keys:
+ value = prior.headers.get(key)
+ if value:
+ return value
+ return None
+
+
+def get_local_git_sha() -> str | None:
+ try:
+ sha = subprocess.check_output(
+ ["git", "rev-parse", "HEAD"],
+ cwd=str(REPO_ROOT),
+ stderr=subprocess.DEVNULL,
+ text=True,
+ ).strip()
+ return sha if sha else None
+ except Exception:
+ return None
+
+
+def get_vercel_deployment_git_sha(deployment_id: str) -> str | None:
+ """
+ If a Vercel token is available, resolve the deployment ID -> git commit SHA.
+
+ Requires `VERCEL_TOKEN` with access to the project owning the deployment.
+ """
+ token = os.environ.get("VERCEL_TOKEN")
+ if not token:
+ return None
+ url = f"https://api.vercel.com/v13/deployments/{deployment_id}"
+ resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=TIMEOUT)
+ if resp.status_code != 200:
+ return None
+ data = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {}
+ if not isinstance(data, dict):
+ return None
+ # Prefer explicit gitSource.sha when present.
+ git_source = data.get("gitSource")
+ if isinstance(git_source, dict):
+ sha = git_source.get("sha")
+ if isinstance(sha, str) and sha:
+ return sha
+ # Fallback: some responses include `meta` fields.
+ meta = data.get("meta")
+ if isinstance(meta, dict):
+ for key in ("githubCommitSha", "gitSha", "commitSha"):
+ sha = meta.get(key)
+ if isinstance(sha, str) and sha:
+ return sha
+ return None
+
+
+class TestDeploymentVersion:
+ """Verify we are testing the expected deployed version."""
+
+ @pytest.mark.live
+ def test_deployment_id_is_available(self, http_session: requests.Session):
+ resp = http_session.get(BASE_URL, timeout=TIMEOUT, allow_redirects=True)
+ assert resp.status_code == 200, f"Base URL returned {resp.status_code}"
+
+ deployment_id = extract_vercel_deployment_id(resp)
+ assert deployment_id, "Could not find Vercel deployment id (x-served-version/x-version)"
+
+ expected_deployment = os.environ.get("DOCS_EXPECTED_VERCEL_DEPLOYMENT_ID")
+ if expected_deployment:
+ assert (
+ deployment_id == expected_deployment
+ ), f"Expected deployment {expected_deployment}, got {deployment_id}"
+
+ if VERIFY_GIT_SHA:
+ local_sha = get_local_git_sha()
+ assert local_sha, "Could not determine local git SHA for docs repo"
+ vercel_sha = get_vercel_deployment_git_sha(deployment_id)
+ if not vercel_sha:
+ pytest.skip("VERCEL_TOKEN missing or deployment git SHA not available via Vercel API")
+ assert (
+ vercel_sha == local_sha
+ ), f"Live site git SHA {vercel_sha} does not match local {local_sha}"
+
+
+class TestSiteAvailability:
+ """Basic site health checks."""
+
+ @pytest.mark.live
+ def test_homepage_loads(self, http_session: requests.Session):
+ """Homepage should return 200 and contain expected content."""
+ response = http_session.get(BASE_URL, timeout=TIMEOUT, allow_redirects=True)
+ assert response.status_code == 200, f"Homepage returned {response.status_code}"
+ assert re.search(r"Source\s*Medium", response.text, flags=re.IGNORECASE), (
+ "Homepage missing SourceMedium branding"
+ )
+
+ @pytest.mark.live
+ def test_robots_txt(self, http_session: requests.Session):
+ """Robots.txt should be accessible."""
+ response = http_session.get(f"{BASE_URL}/robots.txt", timeout=TIMEOUT, allow_redirects=True)
+ assert response.status_code in [200, 404], f"Unexpected status: {response.status_code}"
+
+
+class TestNavigationLinks:
+ """Validate all navigation links from docs.json resolve to live pages."""
+
+ @staticmethod
+ def extract_page_refs(obj: dict | list | str, refs: list | None = None) -> list[str]:
+ """Recursively extract page references from docs.json structure."""
+ if refs is None:
+ refs = []
+
+ if isinstance(obj, str):
+ # Skip external URLs and anchors
+ if not obj.startswith(("http://", "https://", "#")):
+ refs.append(obj)
+ elif isinstance(obj, list):
+ for item in obj:
+ TestNavigationLinks.extract_page_refs(item, refs)
+ elif isinstance(obj, dict):
+ # Check for page references in navigation structure
+ for key in ["pages", "tabs", "groups", "navigation"]:
+ if key in obj:
+ TestNavigationLinks.extract_page_refs(obj[key], refs)
+ # Also check 'href' in card-style references
+ if "href" in obj and not obj["href"].startswith(("http://", "https://")):
+ refs.append(obj["href"])
+
+ return refs
+
+ @pytest.fixture(scope="class")
+ def docs_json(self) -> dict:
+ """Load docs.json navigation config."""
+ docs_json_path = REPO_ROOT / "docs.json"
+ assert docs_json_path.exists(), f"docs.json not found at {docs_json_path}"
+ with open(docs_json_path) as f:
+ return json.load(f)
+
+ @pytest.fixture(scope="class")
+ def page_refs(self, docs_json: dict) -> list[str]:
+ """Extract all page references from docs.json."""
+ refs = self.extract_page_refs(docs_json)
+ # Deduplicate while preserving order
+ seen = set()
+ unique_refs = []
+ for ref in refs:
+ norm = normalize_route(ref)
+ if norm and norm not in seen:
+ seen.add(norm)
+ unique_refs.append(norm)
+ return unique_refs
+
+ def test_docs_json_valid(self, docs_json: dict):
+ """docs.json should be valid and have expected structure."""
+ assert "navigation" in docs_json or "tabs" in docs_json, "Missing navigation structure"
+
+ def test_all_nav_pages_exist_locally(self, page_refs: list[str]):
+ """All navigation refs should have corresponding .mdx files."""
+ missing = []
+ for ref in page_refs:
+ clean_ref = ref.lstrip("/")
+ mdx_path = REPO_ROOT / f"{clean_ref}.mdx"
+ index_path = REPO_ROOT / clean_ref / "index.mdx"
+ if not mdx_path.exists() and not index_path.exists():
+ missing.append(ref)
+
+ assert not missing, f"Missing .mdx files for nav refs: {missing[:10]}{'...' if len(missing) > 10 else ''}"
+
+ @pytest.mark.live
+ def test_nav_pages_load_on_site(self, http_session: requests.Session, page_refs: list[str]):
+ """All navigation pages should load successfully on live site."""
+ failed = []
+ warnings = []
+
+ def fetch(ref: str):
+ url = urljoin(BASE_URL + "/", ref.lstrip("/"))
+ try:
+ response = http_session.get(url, timeout=TIMEOUT, allow_redirects=True)
+ return ref, response.status_code, None
+ except requests.TooManyRedirects:
+ return ref, None, "redirect loop"
+ except requests.RequestException as e:
+ return ref, None, str(e)
+
+ with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
+ futures = [executor.submit(fetch, ref) for ref in page_refs]
+ for fut in as_completed(futures):
+ ref, status_code, err = fut.result()
+ if err == "redirect loop":
+ if FAIL_ON_REDIRECT_LOOPS:
+ failed.append((ref, "redirect loop"))
+ else:
+ warnings.append((ref, "redirect loop"))
+ elif err is not None:
+ failed.append((ref, err))
+ elif status_code != 200:
+ failed.append((ref, status_code))
+
+ # Print warnings but don't fail on redirect loops (site-side issue)
+ if warnings:
+ warning_msg = "\n".join([f" {ref}: {status}" for ref, status in warnings])
+ print(f"\nWARNING: Site redirect issues (not doc issues):\n{warning_msg}")
+
+ if failed:
+ failure_msg = "\n".join([f" {ref}: {status}" for ref, status in failed[:20]])
+ pytest.fail(f"Navigation pages failed to load:\n{failure_msg}")
+
+
+class TestInternalLinks:
+ """Validate internal links within MDX files."""
+
+ @staticmethod
+ def extract_internal_links(mdx_content: str) -> list[str]:
+ """Extract internal links from MDX content."""
+ mdx_content = strip_fenced_code_blocks(mdx_content)
+ links = []
+
+ # Markdown links: [text](/path) or [text](path)
+ md_links = re.findall(r'\[([^\]]*)\]\((/[^)#]+)', mdx_content)
+ links.extend([link for _, link in md_links])
+
+ # href attributes: href="/path" or href='/path'
+ href_links = re.findall(r'href=["\'](/[^"\'#]+)', mdx_content)
+ links.extend(href_links)
+
+ # Filter out external links and anchors
+ internal_links = []
+ for link in links:
+ link = normalize_route(link)
+ if not link or link.startswith(("http://", "https://", "#")):
+ continue
+ if is_asset_path(link):
+ continue
+ internal_links.append(link)
+
+ return list(set(internal_links))
+
+ @pytest.fixture(scope="class")
+ def redirect_sources(self) -> set[str]:
+ """Load redirect source paths from docs.json."""
+ docs_json_path = REPO_ROOT / "docs.json"
+ if not docs_json_path.exists():
+ return set()
+ with open(docs_json_path) as f:
+ data = json.load(f)
+ redirects = data.get("redirects", [])
+ return {r.get("source", "").rstrip("/") for r in redirects}
+
+ @pytest.fixture(scope="class")
+ def all_mdx_files(self) -> list[Path]:
+ """Get all MDX files in the repo."""
+ return list(REPO_ROOT.glob("**/*.mdx"))
+
+ def test_internal_links_have_targets(self, all_mdx_files: list[Path], redirect_sources: set[str]):
+ """All internal links should point to existing files or valid redirects."""
+ broken_links = []
+
+ for mdx_file in all_mdx_files:
+ content = mdx_file.read_text(encoding="utf-8", errors="ignore")
+ links = self.extract_internal_links(content)
+
+ for link in links:
+ # Normalize link for comparison
+ normalized_link = normalize_route(link)
+
+ # Skip if this link has a redirect configured
+ if normalized_link in redirect_sources:
+ continue
+
+ # Remove leading slash and add .mdx extension
+ clean_link = normalized_link.lstrip("/")
+ target_path = REPO_ROOT / f"{clean_link}.mdx"
+
+ # Also check without .mdx for index files
+ target_index = REPO_ROOT / clean_link / "index.mdx"
+
+ if not target_path.exists() and not target_index.exists():
+ # Check if it's a directory with content
+ target_dir = REPO_ROOT / clean_link
+ if not target_dir.is_dir():
+ rel_file = mdx_file.relative_to(REPO_ROOT)
+ broken_links.append(f"{rel_file}: {normalized_link}")
+
+ if broken_links:
+ msg = "\n".join(broken_links[:20])
+ pytest.fail(f"Broken internal links found:\n{msg}")
+
+
+class TestTableDocumentation:
+ """Validate sm_transformed_v2 table documentation."""
+
+ TABLE_DOCS_PATH = REPO_ROOT / "data-activation" / "data-tables" / "sm_transformed_v2"
+
+ @pytest.fixture(scope="class")
+ def table_doc_files(self) -> list[Path]:
+ """Get all table documentation files."""
+ if not self.TABLE_DOCS_PATH.exists():
+ pytest.skip("Table docs directory not found")
+ return list(self.TABLE_DOCS_PATH.glob("*.mdx"))
+
+ def test_table_docs_have_required_frontmatter(self, table_doc_files: list[Path]):
+ """All table docs should have title and description."""
+ missing_frontmatter = []
+
+ for doc_file in table_doc_files:
+ content = doc_file.read_text()
+
+ # Check for frontmatter
+ if not content.startswith("---"):
+ missing_frontmatter.append(f"{doc_file.name}: No frontmatter")
+ continue
+
+ # Extract frontmatter
+ parts = content.split("---", 2)
+ if len(parts) < 3:
+ missing_frontmatter.append(f"{doc_file.name}: Invalid frontmatter")
+ continue
+
+ frontmatter = parts[1]
+ if "title:" not in frontmatter:
+ missing_frontmatter.append(f"{doc_file.name}: Missing title")
+ if "description:" not in frontmatter:
+ missing_frontmatter.append(f"{doc_file.name}: Missing description")
+
+ assert not missing_frontmatter, f"Frontmatter issues:\n" + "\n".join(missing_frontmatter)
+
+ def test_no_excluded_columns_documented(self, table_doc_files: list[Path]):
+ """Table docs should not document MDW-excluded columns."""
+ # Columns that should never appear in docs
+ excluded_patterns = [
+ r"name:\s*\w+_array\b", # _array suffix columns
+ r"name:\s*_synced_at\b", # _synced_at columns
+ r"name:\s*sm_order_referrer_source\b", # explicitly excluded
+ ]
+
+ violations = []
+
+ for doc_file in table_doc_files:
+ content = doc_file.read_text(encoding="utf-8", errors="ignore")
+ # Only scan YAML blocks to avoid matching prose/examples.
+ yaml_blocks = re.findall(r"```yaml\\s*(.*?)\\s*```", content, flags=re.DOTALL)
+ haystack = "\n".join(yaml_blocks) if yaml_blocks else content
+
+ for pattern in excluded_patterns:
+ matches = re.findall(pattern, haystack)
+ if matches:
+ violations.append(f"{doc_file.name}: Found excluded column(s): {matches}")
+
+ assert not violations, f"Excluded columns found in docs:\n" + "\n".join(violations)
+
+ def test_no_masterset_references(self, table_doc_files: list[Path]):
+ """Table docs should use sm_transformed_v2, not masterset."""
+ violations = []
+
+ for doc_file in table_doc_files:
+ content = doc_file.read_text(encoding="utf-8", errors="ignore")
+
+ if "masterset" in content.lower():
+ violations.append(doc_file.name)
+
+ assert not violations, f"Files referencing 'masterset' (should be sm_transformed_v2): {violations}"
+
+ @pytest.mark.live
+ def test_table_doc_pages_load(self, http_session: requests.Session, table_doc_files: list[Path]):
+ """All table doc pages should load on live site."""
+ failed = []
+
+ def fetch(doc_file: Path):
+ rel_path = doc_file.relative_to(REPO_ROOT).with_suffix("")
+ url = urljoin(BASE_URL + "/", str(rel_path))
+ try:
+ response = http_session.get(url, timeout=TIMEOUT, allow_redirects=True)
+ return doc_file.name, response.status_code, None
+ except requests.TooManyRedirects:
+ return doc_file.name, None, "redirect loop"
+ except requests.RequestException as e:
+ return doc_file.name, None, str(e)
+
+ with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
+ futures = [executor.submit(fetch, doc_file) for doc_file in table_doc_files]
+ for fut in as_completed(futures):
+ name, status_code, err = fut.result()
+ if err == "redirect loop":
+ if FAIL_ON_REDIRECT_LOOPS:
+ failed.append((name, "redirect loop"))
+ elif err is not None:
+ failed.append((name, err))
+ elif status_code != 200:
+ failed.append((name, status_code))
+
+ if failed:
+ msg = "\n".join([f" {name}: {status}" for name, status in failed])
+ pytest.fail(f"Table doc pages failed to load:\n{msg}")
+
+
+class TestKeyPages:
+ """Validate critical pages load with expected content."""
+
+ KEY_PAGES = [
+ ("/data-activation/data-tables/sm_transformed_v2", "sm_transformed_v2"),
+ ("/data-activation/managed-data-warehouse/modeling", "SQL"),
+ ("/onboarding/data-docs/dimensions", "dimension"),
+ ("/help-center/common-analyses/roas", "ROAS"),
+ ]
+
+ @pytest.mark.live
+ @pytest.mark.parametrize("path,expected_content", KEY_PAGES)
+ def test_key_page_loads_with_content(self, http_session: requests.Session, path: str, expected_content: str):
+ """Key pages should load and contain expected content."""
+ url = urljoin(BASE_URL, path)
+ response = http_session.get(url, timeout=TIMEOUT, allow_redirects=True)
+
+ assert response.status_code == 200, f"{path} returned {response.status_code}"
+ assert expected_content.lower() in response.text.lower(), (
+ f"{path} missing expected content: '{expected_content}'"
+ )
+
+
+class TestSQLExamples:
+ """Validate SQL examples use correct dataset naming."""
+
+ @pytest.fixture(scope="class")
+ def modeling_doc(self) -> str:
+ """Load modeling.mdx content."""
+ modeling_path = REPO_ROOT / "data-activation" / "managed-data-warehouse" / "modeling.mdx"
+ if not modeling_path.exists():
+ pytest.skip("modeling.mdx not found")
+ return modeling_path.read_text()
+
+ def test_sql_uses_sm_transformed_v2(self, modeling_doc: str):
+ """SQL examples should reference sm_transformed_v2, not masterset."""
+ # Check for masterset in SQL blocks
+ sql_blocks = re.findall(r"```sql\n(.*?)```", modeling_doc, re.DOTALL)
+
+ for i, sql in enumerate(sql_blocks):
+ assert "masterset" not in sql.lower(), (
+ f"SQL block {i+1} references 'masterset' instead of 'sm_transformed_v2'"
+ )
+
+ def test_sql_has_correct_dataset_pattern(self, modeling_doc: str):
+ """SQL examples should use your_project.sm_transformed_v2.table pattern."""
+ sql_blocks = re.findall(r"```sql\\s*(.*?)\\s*```", modeling_doc, re.DOTALL)
+ haystack = "\n".join(sql_blocks)
+ table_refs = re.findall(r'(?:from|join)\\s+`?([^\\s`]+)`?', haystack, re.IGNORECASE)
+
+ for ref in table_refs:
+ if "your_project" in ref.lower():
+ assert "sm_transformed_v2" in ref, (
+ f"Table reference '{ref}' should use sm_transformed_v2 dataset"
+ )
+
+
+# Pytest configuration
+def pytest_configure(config):
+ """Register custom markers."""
+ config.addinivalue_line(
+ "markers", "live: marks tests that hit the live site (may be slow)"
+ )
+
+
+if __name__ == "__main__":
+ pytest.main([__file__, "-v"])
diff --git a/v2-mint.json b/v2-mint.json
deleted file mode 100644
index 67d4450..0000000
--- a/v2-mint.json
+++ /dev/null
@@ -1,292 +0,0 @@
-{
- "name": "SourceMedium",
- "analytics": {
- "ga4": {
- "measurementId": "G-LKSGE9NY1B"
- }
- },
- "logo": {
- "light": "/logo/light.png",
- "dark": "/logo/dark.png"
- },
- "modeToggle": {
- "default": "light",
- "isHidden": true
- },
- "favicon": "/favicon.png",
- "colors": {
- "primary": "#A084FC",
- "light": "#BAA6FC",
- "dark": "#A084FC"
- },
- "topbarCtaButton": {
- "name": "Request a Demo",
- "url": "https://www.sourcemedium.com/book-demo-web"
- },
- "topbarLinks": [
- {
- "name": "Customer Case Studies",
- "url": "https://www.sourcemedium.com/case-study"
- },
- {
- "name": "Blog",
- "url": "https://www.sourcemedium.com/blog"
- }
- ],
- "primaryTab": {
- "name": "Help Center"
- },
- "tabs": [
- {
- "name": "Data Integrations & Inputs",
- "url": "data-inputs"
- },
- {
- "name": "Metrics & Dimensions",
- "url": "https://airtable.com/appDL2NQzZOtufpl5/shriuBU2tZWDF2MJH/tblGNgK3rEziVojnH/viwGkJF0DcplUEAxY"
- },
- {
- "name": "SourceMedium Bootcamp",
- "url": "source-medium-university"
- }
- ],
- "feedback": {
- "thumbsRating": true
- },
- "navigation": [
- {
- "group": "Onboarding",
- "pages": [
- "what is SM",
- "working with SM",
- {
- "group": "Onboarding Materials",
- "pages": [
-
- ]
- },
- "creating & managing access groups"
- ]
- },
- {
- "group": "Integrations & Data Enrichment Tools",
- "pages": [
- {
- "group": "Integrations",
- "pages": [
- {
- "group": "Proprietary Partner Integrations",
- "pages": [
- {
- "group": "Elevar",
- "pages": [
- "elevar integration instructions"
- ]
- },
- {
- "group": "FERMÁT",
- "pages": [
- "FERMÁT integration instructions"
- ]
- }
- ]
- },
- {
- "group": "Ecommerce",
- "pages": [
- {
- "group": "Shopify",
- "pages": [
- "shopify integration instructions",
- "gift card revenue nuance"
- ]
- }
- ]
- },
- {
- "group": "Subscription",
- "pages": [
- {
- "group": "ReCharge",
- "pages": [
- "recharge integration instructions",
- "prepaid subscription nuance"
- ]
- }
- ]
- },
- {
- "group": "Marketing & Advertising",
- "pages": [
- {
- "group": "Meta",
- "pages": [
- "meta integration instructions"
- ]
- },
- {
- "group": "Google Ads",
- "pages": [
- "google ads integration instructions"
- ]
- },
- {
- "group": "Impact Radius",
- "pages": [
- "impact integration instructions"
- ]
- }
- ]
- },
- {
- "group": "Site Analytics & Attribution",
- "pages": [
- {
- "group": "Google Analytics 4",
- "pages": [
- "ga4 integration instructions"
- ]
- }
- ]
- },
- {
- "group": "Email & SMS",
- "pages": [
- {
- "group": "Klaviyo",
- "pages": [
- "Klaviyo integration instructions"
- ]
- }
- ]
- }
- ]
- },
- {
- "group": "Proprietary Data Enrichment Tools",
- "pages": [
- "configuration sheet overview",
- {
- "group": "Setting Targets",
- "pages": [
-
- ]
- },
- {
- "group": "channel mapping",
- "pages": [
-
- ]
- },
- {
- "group": "Custom Marketing Costs",
- "pages": [
-
- ]
- },
- {
- "group": "Custom Sales",
- "pages": [
-
- ]
- },
- {
- "group": "COGS",
- "pages": [
-
- ]
- }
- ]
- }
- ]
- },
- {
- "group": "Data Transformation",
- "pages": [
- "SM data modeling philosophy",
- "SM data cleaning decisions",
- {
- "group": "Data Enrichment Methods",
- "pages": [
- "Attribution waterfall",
- "Channel mapping",
- "Unifying subscription data",
- "financials - cogs/product costs, targets"
- ]
- },
- {
- "group": "Known source data issues",
- "pages": [
- {
- "group": "ReCharge",
- "pages": [
-
- ]
- }
- ]
- }
- ]
- },
- {
- "group": "Data Activation",
- "pages": [
- {
- "group": "Managed Warehouse",
- "pages": [
- "Building on top of SM",
- "Naming Conventions",
- {
- "group": "Available schemas",
- "pages": [
-
- ]
- },
- "Query Building",
- "Important Join Keys & Join Recipes",
- {
- "group": "dashboard building & BI tool education",
- "pages": [
-
- ]
- },
- "How to use BigQuery"
- ]
- },
- {
- "group": "Managed BI",
- "pages": [
- {
- "group": "Dashboard Education",
- "pages": [
-
- ]
- },
- {
- "group": "Template Gallery",
- "pages": [
-
- ]
- }
- ]
- },
- {
- "group": "Metric & dimension definitions",
- "pages": [
-
- ]
- },
- {
- "group": "Common Analyses",
- "pages": [
-
- ]
- }
- ]
- }
- ],
- "footerSocials":
- {
- "twitter": "https://twitter.com/sourcemediumhq",
- "linkedin": "https://www.linkedin.com/company/sourcemedium/"
- }
-}
\ No newline at end of file
diff --git a/yaml-files/latest-v2-schemas-10-20-25.json b/yaml-files/latest-v2-schemas-10-20-25.json
new file mode 100644
index 0000000..141fa94
--- /dev/null
+++ b/yaml-files/latest-v2-schemas-10-20-25.json
@@ -0,0 +1,25441 @@
+[{
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_tags_array",
+ "original_column_name": "customer_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Array of all tags associated with a customer. Preferred for robust filtering (use UNNEST) and programmatic tag operations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_tags_array",
+ "original_column_name": "order_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Array of tags that the shop owner has attached to the order. Preferred for robust filtering (use UNNEST) and programmatic tag operations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_tags_array",
+ "original_column_name": "product_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Tags that the shop owner has attached to the product in an array format.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_array",
+ "original_column_name": "customer_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Array of all tags associated with a customer. Preferred for robust filtering (use UNNEST) and programmatic tag operations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_array",
+ "original_column_name": "customer_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Array of all tags associated with a customer. Preferred for robust filtering (use UNNEST) and programmatic tag operations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_tags_array",
+ "original_column_name": "order_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Tags that the shop owner has attached to the order in an array format. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_tags_array",
+ "original_column_name": "product_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Tags that the shop owner has attached to the product in an array format.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_tags_array",
+ "original_column_name": "order_product_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Array of unique product tags included in the order (de-duplicated from order lines). Prefer array for exact matching; CSV for quick text filters. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_variant_titles_array",
+ "original_column_name": "order_product_variant_titles_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Array of product variant titles in the order (e.g., size/color; aggregated from order lines). Variant titles can change; use stable variant IDs for joins when available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_array",
+ "original_column_name": "customer_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Array of all tags associated with a customer. Preferred for robust filtering (use UNNEST) and programmatic tag operations. Snapshot at time of order (free-form, set by merchants/apps). Tags reflect state at processing time; use ARRAY_TO_STRING for filtering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_tags_array",
+ "original_column_name": "order_tags_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Array of tags that the shop owner has attached to the order. Preferred for robust filtering (use UNNEST) and programmatic tag operations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_titles_array",
+ "original_column_name": "order_product_titles_array",
+ "data_type": "ARRAY\u003cSTRING\u003e",
+ "is_nullable": "false",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Array of product titles included in the order (aggregated from order lines). Product titles can change; prefer product/variant IDs for stable joins. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "is_default_address_for_customer",
+ "original_column_name": "is_default_address_for_customer",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Boolean indicating whether this address is the default/primary address for the customer. Used to identify the customer\u0027s preferred address for shipping and billing. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "is_customer_email_verified",
+ "original_column_name": "is_customer_email_verified",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Whether the customer\u0027s email has been verified.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.3122512162759836",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "has_customer_consented_to_marketing",
+ "original_column_name": "has_customer_consented_to_marketing",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Whether the customer has consented to receive marketing communications.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.1875533483355323",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "is_price_tax_inclusive",
+ "original_column_name": "is_price_tax_inclusive",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Whether taxes are included in the order subtotal.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "is_product_gift_card",
+ "original_column_name": "is_product_gift_card",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Whether the product is a gift card.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "is_ticket_one_touch",
+ "original_column_name": "is_ticket_one_touch",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Flag indicating if the ticket was resolved with a single touch",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "is_ticket_spam",
+ "original_column_name": "is_ticket_spam",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Whether the ticket is marked as spam",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "is_ticket_from_agent",
+ "original_column_name": "is_ticket_from_agent",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Indicates whether the ticket was initiated by an agent (true) or customer (false)",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "is_ticket_unread",
+ "original_column_name": "is_ticket_unread",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Indicates whether the ticket has unread messages",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "has_customer_consented_to_marketing",
+ "original_column_name": "has_customer_consented_to_marketing",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Whether the customer has consented to receive marketing communications.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.3133787249093647",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_customer_email_verified",
+ "original_column_name": "is_customer_email_verified",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Whether the customer\u0027s email has been verified.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.1935394961689",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_order_only_gift_cards",
+ "original_column_name": "is_order_only_gift_cards",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Whether the order associated with the line item only contains gift cards. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_order_sm_valid",
+ "original_column_name": "is_order_sm_valid",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "True if order is not voided, cancelled, uncollectible, draft, or refunded. Use WHERE is_order_sm_valid \u003d TRUE to exclude test/invalid orders from revenue.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_product_gift_card",
+ "original_column_name": "is_product_gift_card",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Whether the product is a gift card.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_order_line_subscription",
+ "original_column_name": "is_order_line_subscription",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Whether the order line is a susbcription order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_order_recurring_subscription",
+ "original_column_name": "is_order_recurring_subscription",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether a subscription order is a repeat subscription order based on the subscription order index or order tag indicators when an index is not available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_subscription_order",
+ "original_column_name": "is_subscription_order",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether the order is a subscription order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_order_sm_valid",
+ "original_column_name": "is_order_sm_valid",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "True if order is not voided, cancelled, uncollectible, draft, or refunded. Use WHERE is_order_sm_valid \u003d TRUE to exclude test/invalid orders from revenue.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_first_subscription_order",
+ "original_column_name": "is_first_subscription_order",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether a subscription order is the first subscription order based on the subscription order index or order tag indicators when an index is not available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_latest_order",
+ "original_column_name": "is_latest_order",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether an order has an order_index_reversed that equals 1. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "is_price_tax_inclusive",
+ "original_column_name": "is_price_tax_inclusive",
+ "data_type": "BOOL",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether taxes are included in the order subtotal.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "latest_refund_date",
+ "original_column_name": "latest_refund_date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The most recent date a refund was processed for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.0825215195093",
+ "column_distinct_count": "2",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-19 00:00:00+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "earliest_refund_date",
+ "original_column_name": "earliest_refund_date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The date of the first refund associated with the order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.942917547568712",
+ "column_distinct_count": "2",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-19 00:00:00+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "latest_refund_date",
+ "original_column_name": "latest_refund_date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The most recent date when a refund was processed for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.158390843292381",
+ "column_distinct_count": "2",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-19 00:00:00+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "earliest_refund_date",
+ "original_column_name": "earliest_refund_date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The earliest date when a refund was processed for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.325577474287641",
+ "column_distinct_count": "2",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-19 00:00:00+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "date",
+ "original_column_name": "date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Calendar date for daily aggregation of performance and attribution metrics.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3183",
+ "column_sample_min": "2016-09-15 00:00:00+00",
+ "column_sample_max": "2025-10-17 00:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "date",
+ "original_column_name": "date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The date when the ad was delivered. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3198",
+ "column_sample_min": "2016-09-17 00:00:00+00",
+ "column_sample_max": "2025-10-18 00:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month",
+ "original_column_name": "cohort_month",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Cohort acquisition month.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "113",
+ "column_sample_min": "2016-04-01 00:00:00+00",
+ "column_sample_max": "2025-10-01 00:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "date",
+ "original_column_name": "date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The date in YYYY-MM-DD format. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2366",
+ "column_sample_min": "2016-01-16 00:00:00+00",
+ "column_sample_max": "2025-10-18 00:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "date",
+ "original_column_name": "date",
+ "data_type": "DATE",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Calendar date for daily aggregation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3278",
+ "column_sample_min": "2016-08-11 00:00:00+00",
+ "column_sample_max": "2025-10-17 00:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_processed_at_local_datetime",
+ "original_column_name": "order_processed_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64775",
+ "column_sample_min": "2016-04-15 06:47:45+00",
+ "column_sample_max": "2025-10-18 09:11:33+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_created_at_local_datetime",
+ "original_column_name": "order_created_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Order created timestamp converted to reporting timezone (from order_created_at UTC).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64953",
+ "column_sample_min": "2016-06-12 23:48:13+00",
+ "column_sample_max": "2025-10-18 10:28:11+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_cancelled_at_local_datetime",
+ "original_column_name": "order_cancelled_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Order cancelled timestamp converted to reporting timezone (from order_cancelled_at UTC). Null if order has not been cancelled.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.003107174326388",
+ "column_distinct_count": "5813",
+ "column_sample_min": "2016-09-16 12:23:13+00",
+ "column_sample_max": "2025-10-17 16:02:45+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_updated_at_local_datetime",
+ "original_column_name": "order_updated_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Order last modified timestamp converted to reporting timezone (from order_updated_at UTC). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "52373",
+ "column_sample_min": "2017-01-03 12:39:00+00",
+ "column_sample_max": "2025-10-18 10:46:35+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_created_at_local_datetime",
+ "original_column_name": "order_created_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Order created timestamp converted to reporting timezone (from order_created_at UTC).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032730010146303145",
+ "column_distinct_count": "57968",
+ "column_sample_min": "2016-08-15 17:17:44+00",
+ "column_sample_max": "2025-10-18 10:28:04+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "refunded_at_local_datetime",
+ "original_column_name": "refunded_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The autogenerated date and time when the refund was processed, converted to the reporting timezone configured in SourceMedium. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12019",
+ "column_sample_min": "2016-08-29 16:23:31+00",
+ "column_sample_max": "2025-10-18 08:31:27+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_closed_at_local_datetime",
+ "original_column_name": "ticket_closed_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Ticket closed timestamp in local timezone.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "8.071997230875736",
+ "column_distinct_count": "26717",
+ "column_sample_min": "2019-09-11 14:23:02.946+00",
+ "column_sample_max": "2025-10-17 23:08:51.904428+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_updated_at_local_datetime",
+ "original_column_name": "ticket_updated_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Ticket latest updated timestamp in local timezone.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "23913",
+ "column_sample_min": "2020-12-30 20:34:45.612+00",
+ "column_sample_max": "2025-10-17 23:08:27.515385+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_last_message_at_local_datetime",
+ "original_column_name": "ticket_last_message_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Timestamp of the last message in the ticket in local timezone.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.09848058525604951",
+ "column_distinct_count": "28617",
+ "column_sample_min": "2019-09-11 13:22:32.946+00",
+ "column_sample_max": "2025-10-17 23:06:03+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_created_at_local_datetime",
+ "original_column_name": "ticket_created_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Timestamp when the ticket was created (local timezone)",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28762",
+ "column_sample_min": "2018-11-03 15:05:02+00",
+ "column_sample_max": "2025-10-17 22:07:49+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system_event_local_datetime",
+ "original_column_name": "source_system_event_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Original event timestamp from the source tracking platform in its local timezone. May differ from event_local_datetime which uses the reporting timezone; use for debugging timestamp discrepancies. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1361654",
+ "column_sample_min": "1978-01-20 19:36:42.094+00",
+ "column_sample_max": "2025-10-18 20:00:13.010+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_local_datetime",
+ "original_column_name": "event_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Event timestamp in the reporting time zone; use for time-series grouping and recency checks. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1387560",
+ "column_sample_min": "2024-02-29 16:00:01.733+00",
+ "column_sample_max": "2025-10-18 13:01:11.104+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_datetime",
+ "original_column_name": "event_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTC timestamp when the event was synced/ingested into the warehouse. Use event_local_datetime for time-series analysis in the reporting timezone. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1376811",
+ "column_sample_min": "2024-03-01 00:00:02.114+00",
+ "column_sample_max": "2025-10-18 20:00:50.360+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_processed_at_local_datetime",
+ "original_column_name": "order_processed_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.000803064494109522",
+ "column_distinct_count": "116216",
+ "column_sample_min": "2016-01-06 18:30:34+00",
+ "column_sample_max": "2025-10-18 10:11:16+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_created_at_local_datetime",
+ "original_column_name": "order_created_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Order created timestamp converted to reporting timezone (from order_created_at UTC). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032136515919626574",
+ "column_distinct_count": "115643",
+ "column_sample_min": "2016-01-20 12:08:53+00",
+ "column_sample_max": "2025-10-18 10:11:20+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_updated_at_local_datetime",
+ "original_column_name": "order_updated_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Order last updated timestamp converted to reporting timezone (from order_updated_at UTC). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "38759",
+ "column_sample_min": "2017-03-02 18:38:43+00",
+ "column_sample_max": "2025-10-18 10:57:17+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_created_at_local_datetime",
+ "original_column_name": "order_created_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Order created timestamp converted to reporting timezone (from order_created_at UTC).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "47565",
+ "column_sample_min": "2016-04-10 09:25:55+00",
+ "column_sample_max": "2025-10-18 07:53:55+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_processed_at_local_datetime",
+ "original_column_name": "order_processed_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Order processed timestamp converted to reporting timezone (from order_processed_at UTC). Primary date field for order analytics and time-based filtering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "47469",
+ "column_sample_min": "2016-04-15 06:47:45+00",
+ "column_sample_max": "2025-10-18 07:32:34+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cancelled_at_local_datetime",
+ "original_column_name": "order_cancelled_at_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Order cancelled timestamp converted to reporting timezone (from order_cancelled_at UTC). Null if order has not been cancelled.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "93.09135947602654",
+ "column_distinct_count": "3291",
+ "column_sample_min": "2016-04-14 00:29:58+00",
+ "column_sample_max": "2025-10-17 02:50:48+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_local_datetime",
+ "original_column_name": "event_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Event timestamp in the reporting timezone for time-based attribution.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "37787",
+ "column_sample_min": "2024-02-29 18:28:33.350+00",
+ "column_sample_max": "2025-10-16 21:39:01.550+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "purchase_local_datetime",
+ "original_column_name": "purchase_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Purchase event timestamp in the reporting timezone for conversion attribution.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "25756",
+ "column_sample_min": "2024-03-01 03:48:06+00",
+ "column_sample_max": "2025-10-16 22:45:02+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_local_datetime",
+ "original_column_name": "event_local_datetime",
+ "data_type": "DATETIME",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Event timestamp in the reporting time zone (hourly bucket).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "14285",
+ "column_sample_min": "2024-03-01 00:00:00+00",
+ "column_sample_max": "2025-10-18 13:00:00+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "discounts",
+ "original_column_name": "discounts",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of the discount applied to the discount entity. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1965",
+ "column_sample_min": "-29988",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_price",
+ "original_column_name": "order_line_price",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The price of a single unit of the product at the time of purchase (before line-level discounts). Multiply by order_line_quantity to get total line revenue. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "tax_line_rate",
+ "original_column_name": "tax_line_rate",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The proportion of the order price that the tax represents. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "63.942206285593763",
+ "column_distinct_count": "151",
+ "column_sample_min": "0",
+ "column_sample_max": "0.2",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "taxes",
+ "original_column_name": "taxes",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of tax associated with a tax line entity, after discounts and before returns. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4529",
+ "column_sample_min": "0",
+ "column_sample_max": "939.62",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_price",
+ "original_column_name": "product_variant_price",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The current retail price for this product variant (per unit). Used for pricing analysis and comparison with order line prices. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "32",
+ "column_sample_min": "0",
+ "column_sample_max": "4147",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_price",
+ "original_column_name": "order_line_price",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "The price of the items purchased in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "781",
+ "column_sample_min": "0",
+ "column_sample_max": "4147",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_gross_sales",
+ "original_column_name": "order_line_gross_sales",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "The number of items in an order multiplied by the price of those items. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "941",
+ "column_sample_min": "0",
+ "column_sample_max": "21262.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_refunds",
+ "original_column_name": "order_line_refunds",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of order line refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1701",
+ "column_sample_min": "-8629.2",
+ "column_sample_max": "5051.13",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_refund_quantity",
+ "original_column_name": "order_line_refund_quantity",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The quantity of order lines that were refunded. This value is always negative. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": "-29",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_tax_refunds",
+ "original_column_name": "order_line_tax_refunds",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of order line tax refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1647",
+ "column_sample_min": "-1017.47",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "source_system_configured_product_cost",
+ "original_column_name": "source_system_configured_product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Landed cost from platform-configured product costs (not SourceMedium configuration sheet). For config-sheet costs, see user_configured_product_cost. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00320921687085309",
+ "column_distinct_count": "459",
+ "column_sample_min": "-1872.33",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_product_cost",
+ "original_column_name": "order_line_product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0040143553346768043",
+ "column_distinct_count": "539",
+ "column_sample_min": "-3785.87",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_product_gross_profit",
+ "original_column_name": "order_line_product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Net order line revenue minus product cost. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00080549670954594148",
+ "column_distinct_count": "4473",
+ "column_sample_min": "-5051.33",
+ "column_sample_max": "194683.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_variant_price",
+ "original_column_name": "product_variant_price",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The price of the product variant at the time of purchase (per unit, before discounts). Use for pricing analysis and discount effectiveness calculations. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "40.926458075805492",
+ "column_distinct_count": "154",
+ "column_sample_min": "0",
+ "column_sample_max": "4147",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_profit",
+ "original_column_name": "order_line_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Net order line revenue and shipping revenue minus order line product cost, order shipping cost, order fulfillment cost, and merchant processing fees. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016098782127132083",
+ "column_distinct_count": "8923",
+ "column_sample_min": "-9836.61",
+ "column_sample_max": "718013.68",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "gross_profit",
+ "original_column_name": "gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "10736",
+ "column_sample_min": "-13771.3",
+ "column_sample_max": "56061.6",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_cost",
+ "original_column_name": "product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The landed cost of an order as defined by the SourceMedium financial cost configuration sheet (or by costs input directly into Shopify) multiplied by the quantity purchased. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2712",
+ "column_sample_min": "-9475.93",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_gross_profit",
+ "original_column_name": "product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Net order revenue minus product cost. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7952",
+ "column_sample_min": "-13771.3",
+ "column_sample_max": "83622.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_conversions",
+ "original_column_name": "ad_platform_reported_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Platform-reported conversion count; may differ from attribution conversions due to tracking methodology.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1413",
+ "column_sample_min": "0",
+ "column_sample_max": "52",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_linear_conversions",
+ "original_column_name": "sm_linear_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Conversion count attributed using linear model distributing credit evenly across valid touchpoints; fractional values.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_last_touch_conversions",
+ "original_column_name": "sm_last_touch_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Conversion count attributed to last valid touchpoint before purchase; fractional conversions possible for shared attribution.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_spend",
+ "original_column_name": "ad_spend",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Total advertising spend for the day at the appropriate waterfall level aggregation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "26034",
+ "column_sample_min": "0",
+ "column_sample_max": "9671.77",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_linear_revenue",
+ "original_column_name": "sm_linear_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Revenue attributed using linear model distributing credit evenly across valid touchpoints in the customer journey.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_revenue",
+ "original_column_name": "ad_platform_reported_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Platform-reported revenue; may differ from attribution revenue due to tracking methodology and attribution windows.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5212",
+ "column_sample_min": "0",
+ "column_sample_max": "128845.56",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_first_touch_conversions",
+ "original_column_name": "sm_first_touch_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Conversion count attributed to first valid non-brand touchpoint; fractional conversions possible for shared attribution.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_spend",
+ "original_column_name": "ad_spend",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The amount of money spent on the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "26488",
+ "column_sample_min": "-590.19580645161284",
+ "column_sample_max": "9671.77",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_revenue",
+ "original_column_name": "ad_platform_reported_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The amount of revenue attributable to the ad, as reported by the advertising platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5593",
+ "column_sample_min": "0",
+ "column_sample_max": "138098.22",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_conversions",
+ "original_column_name": "ad_platform_reported_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The number of conversions attributable to the ad, as reported by the advertising platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1484",
+ "column_sample_min": "0",
+ "column_sample_max": "201",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_product_cost",
+ "original_column_name": "order_product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Product cost (COGS) for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15170",
+ "column_sample_min": "-2791724.44",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_product_gross_profit",
+ "original_column_name": "order_product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Product gross profit (revenue minus product cost) for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "20749",
+ "column_sample_min": "-2841.39",
+ "column_sample_max": "5679224.24",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_product_gross_profit",
+ "original_column_name": "cohort_month_product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total product gross profit for the acquisition month only (baseline for cohort profitability calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "38746",
+ "column_sample_min": "-13155.11",
+ "column_sample_max": "6973078.09",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_product_gross_profit",
+ "original_column_name": "cumulative_product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of product gross profit from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "75659",
+ "column_sample_min": "-13155.11",
+ "column_sample_max": "6891896.64",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_product_cost",
+ "original_column_name": "cumulative_order_product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of product costs from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "66710",
+ "column_sample_min": "-3351841.89",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_gross_profit",
+ "original_column_name": "cumulative_order_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of gross profit from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "81097",
+ "column_sample_min": "-12929.79",
+ "column_sample_max": "6711082.02",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_gross_profit",
+ "original_column_name": "order_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total gross profit including all costs for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "22888",
+ "column_sample_min": "-2549",
+ "column_sample_max": "6551953.22",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cost_per_acquisition",
+ "original_column_name": "cost_per_acquisition",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Customer acquisition cost for the cohort based on marketing spend.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "163",
+ "column_sample_min": "0",
+ "column_sample_max": "88617.26",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_gross_profit",
+ "original_column_name": "cohort_month_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total gross profit for the acquisition month only (baseline for cohort profitability calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "42721",
+ "column_sample_min": "-12929.79",
+ "column_sample_max": "6828732.46",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_order_conversion_rate",
+ "original_column_name": "target_order_conversion_rate",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The order conversion rate target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_revenue",
+ "original_column_name": "ad_platform_reported_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The amount of revenue attributable to the ads, as reported by the advertising platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1171",
+ "column_sample_min": "0",
+ "column_sample_max": "417212.63",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "product_gross_profit",
+ "original_column_name": "product_gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Net order line revenue minus product cost. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2240",
+ "column_sample_min": "-6341.33",
+ "column_sample_max": "892274.77",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_order_gross_revenue",
+ "original_column_name": "target_order_gross_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_return_on_ad_spend",
+ "original_column_name": "target_return_on_ad_spend",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The return on ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": "0",
+ "column_sample_max": "3.5",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_order_count",
+ "original_column_name": "target_order_count",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The order count target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "gross_profit",
+ "original_column_name": "gross_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Net order revenue and shipping revenue minus order product cost, order shipping cost, order fulfillment cost, and merchant processing fees. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2206",
+ "column_sample_min": "-2445.73",
+ "column_sample_max": "371960.93",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_average_order_value",
+ "original_column_name": "target_average_order_value",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The average order value target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_conversions",
+ "original_column_name": "ad_platform_reported_conversions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of conversions attributable to ads, as reported by the advertising platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "334",
+ "column_sample_min": "0",
+ "column_sample_max": "227",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "net_profit",
+ "original_column_name": "net_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Gross profit minus ad spend and operating expenses. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3552",
+ "column_sample_min": "-140188.82",
+ "column_sample_max": "380357.56",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_order_net_revenue",
+ "original_column_name": "target_order_net_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The net order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": "0",
+ "column_sample_max": "81780000",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_website_sessions",
+ "original_column_name": "target_website_sessions",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The website sessions target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_total_order_revenue",
+ "original_column_name": "target_total_order_revenue",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The total order revenue target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": "0",
+ "column_sample_max": "17672000",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "contribution_profit",
+ "original_column_name": "contribution_profit",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Gross profit minus ad spend. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3528",
+ "column_sample_min": "-133850.38",
+ "column_sample_max": "700168.66",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "operating_expenses",
+ "original_column_name": "operating_expenses",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The cost the business incurs while performing its normal operational activities. This data is entered into the Financial Cost - Operating Expenses tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_cost_per_acquisition",
+ "original_column_name": "target_cost_per_acquisition",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The cost per acquisition target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_merchant_processing_fees",
+ "original_column_name": "order_merchant_processing_fees",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The payment processing fees for orders. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1582",
+ "column_sample_min": "-144772.8",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_product_cost",
+ "original_column_name": "order_product_cost",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The landed cost of orders as defined by the SourceMedium financial cost configuration sheet (or input into Shopify) multiplied by the quantity purchased. The SourceMedium financial cost configuration overrides any costs input into Shopify. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2011",
+ "column_sample_min": "-389359.39",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_spend",
+ "original_column_name": "ad_spend",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The amount of money spent on ads. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1342",
+ "column_sample_min": "-302.53741935483868",
+ "column_sample_max": "57616.229999999996",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "target_ad_spend",
+ "original_column_name": "target_ad_spend",
+ "data_type": "FLOAT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The ad spend target for the store. This data is entered in the Targets tab of the SourceMedium configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": "0",
+ "column_sample_max": "404811",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "discount_index",
+ "original_column_name": "discount_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "An ordered index that can be used to identify the discount application and indicate the precedence of the discount application for calculations. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "33",
+ "column_sample_min": "0",
+ "column_sample_max": "46",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_index_reversed",
+ "original_column_name": "order_index_reversed",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Ordered index identifying the sequential position of an order in a customer\u0027s order history, in reverse order.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "73",
+ "column_sample_min": "1",
+ "column_sample_max": "123",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_index",
+ "original_column_name": "order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Ordered index identifying the sequential position of an order in a customer\u0027s order history.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "75",
+ "column_sample_min": "1",
+ "column_sample_max": "121",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_resolution_time_hours",
+ "original_column_name": "ticket_resolution_time_hours",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Time taken to resolve the ticket in hours. In rare occasions where ticket creation time is after ticket closed time, the resolution time is 0.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "7.8599574571956623",
+ "column_distinct_count": "3452",
+ "column_sample_min": "0",
+ "column_sample_max": "51809",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_funnel_event_rank",
+ "original_column_name": "sm_funnel_event_rank",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Sequential rank of the event within the user\u0027s funnel journey (1 \u003d first event, 2 \u003d second, etc.). Used for funnel step analysis and understanding user progression through conversion paths. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": "1",
+ "column_sample_max": "9",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_index",
+ "original_column_name": "valid_order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Ordered index identifying the sequential position of a valid order in a customer\u0027s valid order history. Only counts orders where is_order_sm_valid \u003d TRUE. See order_sequence for all orders.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "23.665278000320463",
+ "column_distinct_count": "5526",
+ "column_sample_min": "1",
+ "column_sample_max": "32822",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_index_reversed",
+ "original_column_name": "valid_order_index_reversed",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "An ordered index in reverse that can be used to identify the sequential position of a valid order relative to a customer\u0027s valid order history. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "23.581194531062604",
+ "column_distinct_count": "5647",
+ "column_sample_min": "1",
+ "column_sample_max": "32817",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_weeks",
+ "original_column_name": "order_to_refund_weeks",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Weeks between order processing date and first refund date for the order/line; derived from days and rounded per model logic. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.5068800898624",
+ "column_distinct_count": "91",
+ "column_sample_min": "0",
+ "column_sample_max": "93",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_order_index",
+ "original_column_name": "subscription_order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Ordered index identifying the sequential position of a subscription order in a customer\u0027s subscription order history.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "96.624990966249911",
+ "column_distinct_count": "31",
+ "column_sample_min": "1",
+ "column_sample_max": "37",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_months",
+ "original_column_name": "order_to_refund_months",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Months between order processing date and first refund date for the order/line; derived from days using average month length. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.535213749139075",
+ "column_distinct_count": "25",
+ "column_sample_min": "0",
+ "column_sample_max": "32",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_index",
+ "original_column_name": "order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "An ordered index that can be used to identify the sequential position of an order relative to a customer\u0027s order history. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00321421970798814",
+ "column_distinct_count": "93",
+ "column_sample_min": "1",
+ "column_sample_max": "123",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_days",
+ "original_column_name": "order_to_refund_days",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Days between order processing and first refund (non-negative; NULL when no refund). Calculated from order_processed_at_local_datetime to earliest_refund_date. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.532407032981254",
+ "column_distinct_count": "534",
+ "column_sample_min": "0",
+ "column_sample_max": "1214",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_days_latest",
+ "original_column_name": "order_to_refund_days_latest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of days between the process date and the most recent refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.7073784412807",
+ "column_distinct_count": "508",
+ "column_sample_min": "0",
+ "column_sample_max": "635",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_latency_days",
+ "original_column_name": "valid_order_latency_days",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of days between the process date of a valid order and the process date of the most recent preceding valid order for a customer. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "75.969513091313743",
+ "column_distinct_count": "953",
+ "column_sample_min": "0",
+ "column_sample_max": "2885",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_index",
+ "original_column_name": "valid_order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Ordered index identifying the sequential position of a valid order in a customer\u0027s valid order history. Only counts orders where is_order_sm_valid \u003d TRUE. See order_sequence for all orders.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "25.174356504073554",
+ "column_distinct_count": "1816",
+ "column_sample_min": "1",
+ "column_sample_max": "32791",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_weeks_latest",
+ "original_column_name": "order_to_refund_weeks_latest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of weeks between the process date and the most recent refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.696396903882658",
+ "column_distinct_count": "97",
+ "column_sample_min": "0",
+ "column_sample_max": "156",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_index",
+ "original_column_name": "order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Ordered index identifying the sequential position of an order in a customer\u0027s order history.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "66",
+ "column_sample_min": "1",
+ "column_sample_max": "99",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_days_earliest",
+ "original_column_name": "order_to_refund_days_earliest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of days between the process date and the first refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.450368844706915",
+ "column_distinct_count": "520",
+ "column_sample_min": "0",
+ "column_sample_max": "960",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_weeks_earliest",
+ "original_column_name": "order_to_refund_weeks_earliest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of weeks between the process date and the first refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.580291894381972",
+ "column_distinct_count": "95",
+ "column_sample_min": "0",
+ "column_sample_max": "156",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_index_reversed",
+ "original_column_name": "valid_order_index_reversed",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "An ordered index that can be used to identify the sequential position of a valid order relative to a customer\u0027s valid order history, in reverse order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "24.406129460615897",
+ "column_distinct_count": "1745",
+ "column_sample_min": "1",
+ "column_sample_max": "32785",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_order_index",
+ "original_column_name": "subscription_order_index",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Ordered index identifying the sequential position of a subscription order in a customer\u0027s subscription order history.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "94.834134161438556",
+ "column_distinct_count": "27",
+ "column_sample_min": "1",
+ "column_sample_max": "27",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_months_earliest",
+ "original_column_name": "order_to_refund_months_earliest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of months between the process date and the first refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.765174379611",
+ "column_distinct_count": "25",
+ "column_sample_min": "0",
+ "column_sample_max": "58",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_to_refund_months_latest",
+ "original_column_name": "order_to_refund_months_latest",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of months between the process date and the most recent refund date for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.575620578508932",
+ "column_distinct_count": "24",
+ "column_sample_min": "0",
+ "column_sample_max": "37",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_latency_days",
+ "original_column_name": "order_latency_days",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The number of days between the order_created_at and the order_processed_at for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "66.044231170456911",
+ "column_distinct_count": "1080",
+ "column_sample_min": "-6",
+ "column_sample_max": "3189",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_index_reversed",
+ "original_column_name": "order_index_reversed",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Ordered index identifying the sequential position of an order in a customer\u0027s order history, in reverse order.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "74",
+ "column_sample_min": "1",
+ "column_sample_max": "117",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "valid_event_index_to_next_purchase",
+ "original_column_name": "valid_event_index_to_next_purchase",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Sequence index from this touchpoint to the next purchase event.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "98",
+ "column_sample_min": "1",
+ "column_sample_max": "229",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_clicks",
+ "original_column_name": "ad_clicks",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Total ad clicks for the day at the appropriate waterfall level aggregation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "528",
+ "column_sample_min": "0",
+ "column_sample_max": "14819",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_impressions",
+ "original_column_name": "ad_impressions",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Total ad impressions for the day at the appropriate waterfall level aggregation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "10314",
+ "column_sample_min": "0",
+ "column_sample_max": "1422683",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_impressions",
+ "original_column_name": "ad_impressions",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The number of times the ad was shown. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "10558",
+ "column_sample_min": "0",
+ "column_sample_max": "673566",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_clicks",
+ "original_column_name": "ad_clicks",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The number of times the ad was clicked. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "520",
+ "column_sample_min": "0",
+ "column_sample_max": "7976",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_inline_link_clicks",
+ "original_column_name": "ad_inline_link_clicks",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The number of clicks on links within the ad that led users to advertiser-specified destinations. Subset of total ad_clicks; excludes non-link engagement clicks (e.g., likes, comments). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "374",
+ "column_sample_min": "0",
+ "column_sample_max": "3208",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "customer_count",
+ "original_column_name": "customer_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Number of distinct customers with orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "460",
+ "column_sample_min": "0",
+ "column_sample_max": "16785",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_count",
+ "original_column_name": "cumulative_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of orders from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3387",
+ "column_sample_min": "3",
+ "column_sample_max": "27611",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_size",
+ "original_column_name": "cohort_size",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Number of customers in the acquisition cohort.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1123",
+ "column_sample_min": "1",
+ "column_sample_max": "6311",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "months_since_first_order",
+ "original_column_name": "months_since_first_order",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Numeric offset from acquisition month (0 \u003d acquisition month, 1 \u003d month +1, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "114",
+ "column_sample_min": "0",
+ "column_sample_max": "114",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_third_order_count",
+ "original_column_name": "cumulative_third_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running count of customers who have placed a third order through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "533",
+ "column_sample_min": "0",
+ "column_sample_max": "1947",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_second_order_count",
+ "original_column_name": "cumulative_second_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running count of customers who have placed a second order through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "842",
+ "column_sample_min": "0",
+ "column_sample_max": "3652",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_order_count",
+ "original_column_name": "cohort_month_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total order count for the acquisition month only (baseline for cohort retention calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1502",
+ "column_sample_min": "3",
+ "column_sample_max": "27611",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_count",
+ "original_column_name": "order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Number of orders placed in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "472",
+ "column_sample_min": "0",
+ "column_sample_max": "19356",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "cancelled_subscription_count",
+ "original_column_name": "cancelled_subscription_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of subscriptions voluntarily cancelled by customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "19",
+ "column_sample_min": "0",
+ "column_sample_max": "52",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "churned_subscription_count",
+ "original_column_name": "churned_subscription_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The cumulative number of subscriptions that have been cancelled. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": "0",
+ "column_sample_max": "35851",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "cancelled_subscriber_count",
+ "original_column_name": "cancelled_subscriber_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of customers who cancelled their final subscription (they do not have any active subscriptions). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": "0",
+ "column_sample_max": "49",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "website_sessions",
+ "original_column_name": "website_sessions",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of sessions on the website. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "500",
+ "column_sample_min": "0",
+ "column_sample_max": "98934",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_customer_order_count",
+ "original_column_name": "new_customer_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of orders from new customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "136",
+ "column_sample_min": "0",
+ "column_sample_max": "1060",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_impressions",
+ "original_column_name": "ad_impressions",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of times ads were shown. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1274",
+ "column_sample_min": "0",
+ "column_sample_max": "2264919",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_clicks",
+ "original_column_name": "ad_clicks",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of times ads were clicked. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "944",
+ "column_sample_min": "0",
+ "column_sample_max": "26049",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "repeat_customer_count",
+ "original_column_name": "repeat_customer_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of unique customers who made at least their second purchase. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "109",
+ "column_sample_min": "0",
+ "column_sample_max": "539",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_count",
+ "original_column_name": "order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of orders placed by customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "171",
+ "column_sample_min": "0",
+ "column_sample_max": "1981",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_subscriber_count",
+ "original_column_name": "new_subscriber_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of customers who converted on their first subscription program. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "18",
+ "column_sample_min": "0",
+ "column_sample_max": "89",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "repeat_customer_order_count",
+ "original_column_name": "repeat_customer_order_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of orders from repeat customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "109",
+ "column_sample_min": "0",
+ "column_sample_max": "654",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "customer_count",
+ "original_column_name": "customer_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of unique customers who made a purchase. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "188",
+ "column_sample_min": "0",
+ "column_sample_max": "1198",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "churned_subscriber_count",
+ "original_column_name": "churned_subscriber_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The cumulative number of customers who have cancelled their final subscription. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4",
+ "column_sample_min": "0",
+ "column_sample_max": "437576",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_subscription_count",
+ "original_column_name": "new_subscription_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of new subscriptions started by customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "22",
+ "column_sample_min": "0",
+ "column_sample_max": "297",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "cancelled_passive_subscription_count",
+ "original_column_name": "cancelled_passive_subscription_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of subscriptions that were terminated without active customer initiation, often due to reasons like the natural expiration of the subscription period. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "active_subscriber_count",
+ "original_column_name": "active_subscriber_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of customers who have at least one active subscription. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "105",
+ "column_sample_min": "0",
+ "column_sample_max": "5532",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "active_subscription_count",
+ "original_column_name": "active_subscription_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of active subscriptions with a store. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "98",
+ "column_sample_min": "0",
+ "column_sample_max": "6278",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_customer_count",
+ "original_column_name": "new_customer_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The number of unique customers who made their first purchase. Special Considerations: Platform coverage varies; tests allow for low coverage thresholds in some cases. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "131",
+ "column_sample_min": "0",
+ "column_sample_max": "2148",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "view_item_event_count",
+ "original_column_name": "view_item_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of product detail page view events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "144",
+ "column_sample_min": "0",
+ "column_sample_max": "11304",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "email_sign_up_event_count",
+ "original_column_name": "email_sign_up_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of email subscription and lead generation events (subscribe, generate_lead) within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "24",
+ "column_sample_min": "0",
+ "column_sample_max": "288",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "remove_from_cart_event_count",
+ "original_column_name": "remove_from_cart_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of cart removal events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "58",
+ "column_sample_min": "0",
+ "column_sample_max": "406",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "add_shipping_info_event_count",
+ "original_column_name": "add_shipping_info_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of shipping information submission events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "6",
+ "column_sample_min": "0",
+ "column_sample_max": "14",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "view_item_list_event_count",
+ "original_column_name": "view_item_list_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of product listing page view events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "100",
+ "column_sample_min": "0",
+ "column_sample_max": "1852",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "begin_checkout_event_count",
+ "original_column_name": "begin_checkout_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of checkout initiation events within the hour for conversion funnel tracking.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": "0",
+ "column_sample_max": "17",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "view_cart_event_count",
+ "original_column_name": "view_cart_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of cart page view events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": "0",
+ "column_sample_max": "9",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "page_view_event_count",
+ "original_column_name": "page_view_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of page view events within the hour for traffic analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "227",
+ "column_sample_min": "0",
+ "column_sample_max": "2557",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "select_item_event_count",
+ "original_column_name": "select_item_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of product selection events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "22",
+ "column_sample_min": "0",
+ "column_sample_max": "8747",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "add_payment_info_event_count",
+ "original_column_name": "add_payment_info_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of payment information submission events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "6",
+ "column_sample_min": "0",
+ "column_sample_max": "14",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "add_to_cart_event_count",
+ "original_column_name": "add_to_cart_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of add-to-cart events within the hour for funnel analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "81",
+ "column_sample_min": "0",
+ "column_sample_max": "1477",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "refund_event_count",
+ "original_column_name": "refund_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of refund events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "purchase_event_count",
+ "original_column_name": "purchase_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of purchase events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": "0",
+ "column_sample_max": "3",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "account_sign_up_event_count",
+ "original_column_name": "account_sign_up_event_count",
+ "data_type": "INT64",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Count of account registration events within the hour.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": "0",
+ "column_sample_max": "3",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_quantity",
+ "original_column_name": "order_line_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The number of units of the product variant ordered in this line item. Used to calculate total line revenue (order_line_price * order_line_quantity). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_line_shipping",
+ "original_column_name": "order_shipping_line_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "The shipping cost amount for this specific shipping line item. Represents the individual shipping charge when multiple shipping methods are used. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "958",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_cart_quantity",
+ "original_column_name": "order_cart_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Total number of items (quantity across all line items) in the order cart. Sum of all order_line_quantity values for the order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "32",
+ "column_sample_min": "0",
+ "column_sample_max": "2520",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_compare_at_price",
+ "original_column_name": "product_variant_compare_at_price",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The original/compare-at price for this product variant (typically MSRP or pre-sale price). Used to show savings/discounts to customers; NULL if no compare-at price is set.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "74.193548387096769",
+ "column_distinct_count": "8",
+ "column_sample_min": "19.99",
+ "column_sample_max": "3254",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_quantity",
+ "original_column_name": "order_line_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "The number of items that were originally purchased in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "25",
+ "column_sample_min": "0",
+ "column_sample_max": "2042",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_duty_refunds",
+ "original_column_name": "order_duty_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of order duty refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "49.955206395148508",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "shipping_refunds",
+ "original_column_name": "shipping_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of shipping refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "209",
+ "column_sample_min": "-563.91",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "shipping_tax_refunds",
+ "original_column_name": "shipping_tax_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The amount of shipping tax refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "87",
+ "column_sample_min": "-48.86",
+ "column_sample_max": "17.33",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_message_count",
+ "original_column_name": "ticket_message_count",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Total number of messages exchanged in the ticket conversation. Includes both customer and agent messages; used for interaction analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "54",
+ "column_sample_min": "0",
+ "column_sample_max": "1146",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_csat_score",
+ "original_column_name": "ticket_csat_score",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "The ticket\u0027s CSAT score given by the customer",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.183964720997253",
+ "column_distinct_count": "5",
+ "column_sample_min": "1",
+ "column_sample_max": "5",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_session_count",
+ "original_column_name": "event_user_session_count",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Session count metric associated with the event/user context when provided by the platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.097794839407892728",
+ "column_distinct_count": "3759",
+ "column_sample_min": "3",
+ "column_sample_max": "133286",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_shipping_revenue",
+ "original_column_name": "event_order_shipping_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Shipping revenue attributed to the event when applicable. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.389184964270825",
+ "column_distinct_count": "65",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_subtotal_revenue",
+ "original_column_name": "event_order_subtotal_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Subtotal revenue (pre-tax, pre-shipping) attributed to the event. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.230283764676415",
+ "column_distinct_count": "3326",
+ "column_sample_min": "0",
+ "column_sample_max": "60942.04",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_revenue",
+ "original_column_name": "event_order_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Revenue attributed to the event when applicable (e.g., purchase events). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.2155666409172",
+ "column_distinct_count": "8892",
+ "column_sample_min": "0",
+ "column_sample_max": "53048322.8",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_taxes",
+ "original_column_name": "event_order_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Taxes attributed to the event when applicable. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.222286939098836",
+ "column_distinct_count": "4157",
+ "column_sample_min": "0",
+ "column_sample_max": "9013.06",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_line_subtotal_revenue",
+ "original_column_name": "event_order_line_subtotal_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Line-level subtotal revenue attributed to the event when available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "92.931581002103485",
+ "column_distinct_count": "4265",
+ "column_sample_min": "0",
+ "column_sample_max": "259777616",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_refunds",
+ "original_column_name": "order_line_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of refunds applied to an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.004812937175126741",
+ "column_distinct_count": "1048",
+ "column_sample_min": "-9016.48",
+ "column_sample_max": "4231.62",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_revenue_before_refunds",
+ "original_column_name": "order_line_net_revenue_before_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross order line revenue minus order line discounts. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0040175486525141817",
+ "column_distinct_count": "2459",
+ "column_sample_min": "-188",
+ "column_sample_max": "150259",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_shipping_discounts",
+ "original_column_name": "order_line_shipping_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of discounts applied to an order shipping line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016019351376462768",
+ "column_distinct_count": "610",
+ "column_sample_min": "-129.95",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_quantity",
+ "original_column_name": "order_line_net_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The quantity of items that were originally purchased for an order line minus the quantity of items refunded. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.003215330696762162",
+ "column_distinct_count": "26",
+ "column_sample_min": "0",
+ "column_sample_max": "726",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_merchant_processing_fees",
+ "original_column_name": "order_line_merchant_processing_fees",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2676",
+ "column_sample_min": "-878.58",
+ "column_sample_max": "5.41",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_taxes",
+ "original_column_name": "order_line_net_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross order line tax minus the order line tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024156923374239058",
+ "column_distinct_count": "4691",
+ "column_sample_min": "-66.76",
+ "column_sample_max": "939.62",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_total_refunds",
+ "original_column_name": "order_line_total_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of refunds for an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.003205693311320906",
+ "column_distinct_count": "1114",
+ "column_sample_min": "-7140.24",
+ "column_sample_max": "4437.29",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_total_discounts",
+ "original_column_name": "order_line_total_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of discounts for an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0040230763660355807",
+ "column_distinct_count": "2079",
+ "column_sample_min": "-2774",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_shipping_refunds",
+ "original_column_name": "order_line_shipping_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of shipping refunds applied to an order shipping line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032006145179874538",
+ "column_distinct_count": "61",
+ "column_sample_min": "-451.11",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_revenue",
+ "original_column_name": "order_line_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross revenue for an order line. Gross revenue is calculated by multiplying the price of an order line by the quantity purchased. Gross revenue excludes revenue from gift card purchases. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.004014065284757791",
+ "column_distinct_count": "1078",
+ "column_sample_min": "0",
+ "column_sample_max": "194683.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_shipping_tax_refunds",
+ "original_column_name": "order_line_shipping_tax_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of shipping tax refunds applied to an order shipping line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00080363241853176359",
+ "column_distinct_count": "53",
+ "column_sample_min": "-30.06",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_duties",
+ "original_column_name": "order_line_gross_duties",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount the customer paid in duties for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00160710985399407",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_shipping",
+ "original_column_name": "order_line_gross_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount the customer paid in shipping for an order shipping line. This does not include shipping tax. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0064279745452208",
+ "column_distinct_count": "876",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_shipping",
+ "original_column_name": "order_line_net_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross shipping revenue for an order shipping line minus shipping discounts and shipping refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032143746835849919",
+ "column_distinct_count": "557",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_duties",
+ "original_column_name": "order_line_net_duties",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross order line duties minus order duty refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0048194319496208714",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_revenue",
+ "original_column_name": "order_line_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross order line revenue minus order line discounts and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016084540344048319",
+ "column_distinct_count": "2836",
+ "column_sample_min": "-3839.02",
+ "column_sample_max": "88877",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_variant_compare_at_price",
+ "original_column_name": "product_variant_compare_at_price",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The original/compare-at price for the product variant (typically MSRP or pre-sale price). Used to show savings/discounts to customers; may be NULL if no compare-at price set. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "96.123264433242483",
+ "column_distinct_count": "51",
+ "column_sample_min": "0",
+ "column_sample_max": "3254",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_quantity",
+ "original_column_name": "order_line_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The quantity of order lines that were originally purchased in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00080466706900020118",
+ "column_distinct_count": "28",
+ "column_sample_min": "0",
+ "column_sample_max": "726",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_total_taxes",
+ "original_column_name": "order_line_total_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of taxes for an order line minus tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016006914987274504",
+ "column_distinct_count": "4774",
+ "column_sample_min": "-91.46",
+ "column_sample_max": "845.25",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_duty_refunds",
+ "original_column_name": "order_line_duty_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of duty refunds applied to an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024139235108103542",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cart_quantity",
+ "original_column_name": "order_cart_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The quantity of items that were originally purchased in an order.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00080401363607126783",
+ "column_distinct_count": "53",
+ "column_sample_min": "0",
+ "column_sample_max": "44015",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "user_configured_product_cost",
+ "original_column_name": "user_configured_product_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The landed cost of an order line as defined by the SourceMedium financial cost configuration sheet multiplied by the quantity purchased. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0048061518743992308",
+ "column_distinct_count": "64",
+ "column_sample_min": "-1170.71",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_fulfillment_cost",
+ "original_column_name": "order_line_fulfillment_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_tax_refunds",
+ "original_column_name": "order_line_tax_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of tax refunds applied to an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.001608104848436118",
+ "column_distinct_count": "1311",
+ "column_sample_min": "-714.02",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_total_revenue",
+ "original_column_name": "order_line_total_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Total order line revenue after factoring in shipping revenue, taxes collected, discounts, and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032086247834178273",
+ "column_distinct_count": "10460",
+ "column_sample_min": "-3839.02",
+ "column_sample_max": "62040",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_taxes",
+ "original_column_name": "order_line_gross_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of taxes associated with an order line, after discounts and before returns. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032122063842601888",
+ "column_distinct_count": "4991",
+ "column_sample_min": "0",
+ "column_sample_max": "939.62",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_refund_quantity",
+ "original_column_name": "order_line_refund_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The quantity of items purchased for an order line that were refunded. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016085316518815798",
+ "column_distinct_count": "8",
+ "column_sample_min": "-52",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_gross_shipping_taxes",
+ "original_column_name": "order_line_gross_shipping_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The gross shipping tax for an order shipping line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0032108140216248328",
+ "column_distinct_count": "264",
+ "column_sample_min": "0",
+ "column_sample_max": "56.38",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_return_cost",
+ "original_column_name": "order_line_return_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_shipping_cost",
+ "original_column_name": "order_line_shipping_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_discounts",
+ "original_column_name": "order_line_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The amount of discounts applied to an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.002414409194070211",
+ "column_distinct_count": "1494",
+ "column_sample_min": "-7170",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_net_shipping_taxes",
+ "original_column_name": "order_line_net_shipping_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The shipping tax for an order shipping line minus shipping tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024196280225186714",
+ "column_distinct_count": "248",
+ "column_sample_min": "-1.96",
+ "column_sample_max": "56.38",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_merchant_processing_fees",
+ "original_column_name": "order_merchant_processing_fees",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The payment processing fees for an order. This data is entered in the Financial Cost - Merchant Processing Fees tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.073418358785031043",
+ "column_distinct_count": "2738",
+ "column_sample_min": "-857.79",
+ "column_sample_max": "2.24",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cart_quantity",
+ "original_column_name": "order_cart_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The quantity of items that were originally purchased in an order.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "32",
+ "column_sample_min": "0",
+ "column_sample_max": "2177",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_revenue_before_refunds",
+ "original_column_name": "order_net_revenue_before_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The gross order revenue minus order discounts. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3122",
+ "column_sample_min": "0",
+ "column_sample_max": "231285.12",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_taxes",
+ "original_column_name": "order_net_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The order tax minus order tax refunds. This does not include shipping taxes. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5810",
+ "column_sample_min": "0",
+ "column_sample_max": "938.87",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_gross_taxes",
+ "original_column_name": "order_gross_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of taxes associated with an order\u0027s lines, after discounts and before returns. This does not include shipping taxes. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "6134",
+ "column_sample_min": "0",
+ "column_sample_max": "1270.5",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_refunds",
+ "original_column_name": "order_shipping_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of shipping refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "48",
+ "column_sample_min": "-319.51",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_total_revenue",
+ "original_column_name": "order_total_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12569",
+ "column_sample_min": "0",
+ "column_sample_max": "175084.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_total_discounts",
+ "original_column_name": "order_total_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of order and shipping discounts for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2419",
+ "column_sample_min": "-11574",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_duties",
+ "original_column_name": "order_net_duties",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The gross order duties minus duty refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_cost",
+ "original_column_name": "order_shipping_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The blended cost per order to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.056851680282995032",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_fulfillment_cost",
+ "original_column_name": "order_fulfillment_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0502302218501465",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_refund_quantity",
+ "original_column_name": "order_refund_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The quantity of order lines originally purchased in an order that were refunded. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "13",
+ "column_sample_min": "-35",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cart_net_quantity",
+ "original_column_name": "order_cart_net_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The quantity of items that were originally purchased in an order minus the quantity of items refunded. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "29",
+ "column_sample_min": "0",
+ "column_sample_max": "44015",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_return_cost",
+ "original_column_name": "order_return_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The blended cost per order to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.078280370668133537",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_total_taxes",
+ "original_column_name": "order_total_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of order and shipping taxes minus order and shipping tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5994",
+ "column_sample_min": "-48.3",
+ "column_sample_max": "1054.3",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_total_refunds",
+ "original_column_name": "order_total_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of order and shipping refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1452",
+ "column_sample_min": "-5799.67",
+ "column_sample_max": "316.86",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_gross_revenue",
+ "original_column_name": "order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The gross revenue for an order, based on an order\u0027s lines. Gross revenue is calculated by multiplying the price of an order\u0027s lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3027",
+ "column_sample_min": "0",
+ "column_sample_max": "231285.12",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_gross_shipping",
+ "original_column_name": "order_gross_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount the customer paid in shipping for an order. This does not include shipping tax. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "661",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_duty_refunds",
+ "original_column_name": "order_duty_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of duty refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_gross_duties",
+ "original_column_name": "order_gross_duties",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount the customer paid in duties for an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_tax_refunds",
+ "original_column_name": "order_tax_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of tax refunds applied to an order. This does not include shipping tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1364",
+ "column_sample_min": "-747.49",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_gross_shipping_taxes",
+ "original_column_name": "order_gross_shipping_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of taxes associated with shipping, after discounts and before returns. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "301",
+ "column_sample_min": "0",
+ "column_sample_max": "74.82",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_refunds",
+ "original_column_name": "order_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The total amount of refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1331",
+ "column_sample_min": "-8629.2",
+ "column_sample_max": "316.86",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_discounts",
+ "original_column_name": "order_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The total amount of discounts applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1875",
+ "column_sample_min": "-5250",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_shipping_taxes",
+ "original_column_name": "order_net_shipping_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The order shipping tax minus shipping tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "272",
+ "column_sample_min": "0",
+ "column_sample_max": "48.86",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_revenue",
+ "original_column_name": "order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The gross order revenue minus order discounts and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3606",
+ "column_sample_min": "-150.31",
+ "column_sample_max": "718013.68",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_net_shipping",
+ "original_column_name": "order_net_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The gross shipping revenue for an order minus shipping discounts and shipping refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "317",
+ "column_sample_min": "0",
+ "column_sample_max": "563.91",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_discounts",
+ "original_column_name": "order_shipping_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of discounts applied to shipping. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "445",
+ "column_sample_min": "-129.9",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_tax_refunds",
+ "original_column_name": "order_shipping_tax_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The amount of shipping tax refunds applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "59",
+ "column_sample_min": "-22.54",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "purchase_order_revenue",
+ "original_column_name": "purchase_order_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Total revenue from the purchase order for attribution calculations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3509",
+ "column_sample_min": "0",
+ "column_sample_max": "10174.52",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_last_touch_revenue",
+ "original_column_name": "sm_last_touch_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Revenue attributed to last valid touchpoint before purchase; excludes brand campaigns and applies email/sms rules.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_first_touch_revenue",
+ "original_column_name": "sm_first_touch_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Revenue attributed to first valid non-brand touchpoint in the customer journey; excludes brand campaigns.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_order_net_revenue",
+ "original_column_name": "cohort_month_order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total net revenue for the acquisition month only (baseline for cohort retention calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "30587",
+ "column_sample_min": "-53.05",
+ "column_sample_max": "10337628.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_cost_of_returns",
+ "original_column_name": "cumulative_order_cost_of_returns",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of return costs from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_merchant_processing_fees",
+ "original_column_name": "order_merchant_processing_fees",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Payment processing fees for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12739",
+ "column_sample_min": "-755843.75",
+ "column_sample_max": "31.72",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_merchant_processing_fees",
+ "original_column_name": "cumulative_order_merchant_processing_fees",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of payment processing fees from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "58454",
+ "column_sample_min": "-1451111.92",
+ "column_sample_max": "31.72",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_net_revenue",
+ "original_column_name": "order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Net revenue after discounts and refunds for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15020",
+ "column_sample_min": "0",
+ "column_sample_max": "9917130.53",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_ordered_quantiy",
+ "original_column_name": "cumulative_ordered_quantiy",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of items ordered from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4596",
+ "column_sample_min": "0",
+ "column_sample_max": "23390",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_gross_revenue",
+ "original_column_name": "order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Gross revenue before discounts and refunds for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "14276",
+ "column_sample_min": "0",
+ "column_sample_max": "17719778.73",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_shipping_cost",
+ "original_column_name": "cumulative_order_shipping_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of shipping costs from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_net_revenue",
+ "original_column_name": "cumulative_order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of net revenue from acquisition month through current month offset for LTV calculation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "66559",
+ "column_sample_min": "-53.05",
+ "column_sample_max": "10159219.11",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_fulfillment_cost",
+ "original_column_name": "cumulative_order_fulfillment_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of fulfillment costs from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_cost_of_returns",
+ "original_column_name": "order_cost_of_returns",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Cost of returns processed in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_fulfillment_cost",
+ "original_column_name": "order_fulfillment_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Fulfillment and handling costs for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_order_gross_revenue",
+ "original_column_name": "cohort_month_order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total gross revenue for the acquisition month only (baseline for cohort retention calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "31587",
+ "column_sample_min": "0",
+ "column_sample_max": "18192187.86",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_shipping_cost",
+ "original_column_name": "order_shipping_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Shipping cost incurred for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "order_shipping",
+ "original_column_name": "order_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Net shipping revenue (charged to customers) for orders in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1976",
+ "column_sample_min": "0",
+ "column_sample_max": "64886.41",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_gross_revenue",
+ "original_column_name": "cumulative_order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of gross revenue from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "67094",
+ "column_sample_min": "0",
+ "column_sample_max": "18327412.46",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_month_ordered_quantity",
+ "original_column_name": "cohort_month_ordered_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total quantity ordered for the acquisition month only (baseline for cohort retention calculations).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2073",
+ "column_sample_min": "0",
+ "column_sample_max": "71597",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "ordered_quantity",
+ "original_column_name": "ordered_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Total quantity of items ordered in the month offset period.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "660",
+ "column_sample_min": "0",
+ "column_sample_max": "66033",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cumulative_order_net_shipping",
+ "original_column_name": "cumulative_order_net_shipping",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Running total of net shipping revenue from acquisition month through current month offset.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "13089",
+ "column_sample_min": "0",
+ "column_sample_max": "72643.58",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_gross_revenue_after_discounts",
+ "original_column_name": "order_gross_revenue_after_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross order revenue minus order discounts. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1985",
+ "column_sample_min": "0",
+ "column_sample_max": "483689.33",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_fulfillment_cost",
+ "original_column_name": "order_fulfillment_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The blended cost to fulfill (pick and pack) orders for customers, considering that fulfillment cost is a variable order cost included in cost of goods sold (COGS). This data is recorded in the Financial Cost - Fulfillment tab of the financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "repeat_customer_order_net_revenue",
+ "original_column_name": "repeat_customer_order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The net order revenue from repeat customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "478",
+ "column_sample_min": "0",
+ "column_sample_max": "115694.88",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_shipping_cost",
+ "original_column_name": "order_shipping_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The blended cost to ship products to customers, considering that shipping costs are variable order costs included in cost of goods sold (COGS). This data is set in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_net_shipping_revenue",
+ "original_column_name": "order_net_shipping_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross shipping revenue for orders minus shipping discounts and shipping refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "708",
+ "column_sample_min": "-169.29",
+ "column_sample_max": "1730.35",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "repeat_customer_order_gross_revenue",
+ "original_column_name": "repeat_customer_order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross order revenue from repeat customers. Special Considerations: Platform aggregation rules can differ; see tests for permitted thresholds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "432",
+ "column_sample_min": "0",
+ "column_sample_max": "421359.23",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_discounts",
+ "original_column_name": "order_discounts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The total amount of discounts applied to orders. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1749",
+ "column_sample_min": "-180668.86",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_refunds",
+ "original_column_name": "order_refunds",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The total amount of refunds applied to orders. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "674",
+ "column_sample_min": "-45098.81",
+ "column_sample_max": "224.47",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_customer_order_gross_revenue",
+ "original_column_name": "new_customer_order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross order revenue from new customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "483",
+ "column_sample_min": "0",
+ "column_sample_max": "1570943.4",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_total_taxes",
+ "original_column_name": "order_total_taxes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The amount of order and shipping taxes minus order and shipping tax refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1679",
+ "column_sample_min": "-684.3",
+ "column_sample_max": "41154.63",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_return_cost",
+ "original_column_name": "order_return_cost",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The blended cost to handle returned products from a customer, considering that the cost of returns is a variable order cost included in cost of goods sold (COGS). This data is entered in the Financial Cost - Shipping tab of the SourceMedium financial cost configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_net_revenue",
+ "original_column_name": "order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross order revenue minus order discounts and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2091",
+ "column_sample_min": "-6294.88",
+ "column_sample_max": "891556.55",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_gross_revenue",
+ "original_column_name": "order_gross_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The gross revenue for orders, based on order lines. Gross revenue is calculated by multiplying the price of an order\u0027s lines by the quantity purchased. Gross revenue excludes revenue from gift card purchases. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2034",
+ "column_sample_min": "0",
+ "column_sample_max": "1620850.55",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "order_total_revenue",
+ "original_column_name": "order_total_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Total order revenue after factoring in shipping revenue, taxes collected, discounts, and refunds. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2213",
+ "column_sample_min": "-5376.88",
+ "column_sample_max": "889032.34",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "new_customer_order_net_revenue",
+ "original_column_name": "new_customer_order_net_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "The net order revenue from new customers. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "478",
+ "column_sample_min": "0",
+ "column_sample_max": "776732",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_order_revenue",
+ "original_column_name": "event_order_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Total revenue attributed to events within the hour aggregated from event_order_revenue field.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "93.000614972778408",
+ "column_distinct_count": "9657",
+ "column_sample_min": "0",
+ "column_sample_max": "88813.16",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_begin_checkout_revenue",
+ "original_column_name": "platform_reported_begin_checkout_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed revenue from begin checkout events.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1690",
+ "column_sample_min": "0",
+ "column_sample_max": "161691.28",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_unique_receives",
+ "original_column_name": "message_unique_receives",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique receives/deliveries.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "805",
+ "column_sample_min": "0",
+ "column_sample_max": "143163",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_order_line_revenue",
+ "original_column_name": "platform_reported_order_line_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed order line revenue from the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1347",
+ "column_sample_min": "0",
+ "column_sample_max": "283507.76",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_order_revenue",
+ "original_column_name": "platform_reported_order_revenue",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed order revenue from the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1720",
+ "column_sample_min": "0",
+ "column_sample_max": "115166.92",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sms_unique_sends",
+ "original_column_name": "sms_unique_sends",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique SMS sends for the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": "0",
+ "column_sample_max": "0",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "list_subscribes",
+ "original_column_name": "list_subscribes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of list subscription events attributed to the message.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "239",
+ "column_sample_min": "0",
+ "column_sample_max": "8706",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_unique_drops",
+ "original_column_name": "message_unique_drops",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique drops/suppressed sends.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "14",
+ "column_sample_min": "0",
+ "column_sample_max": "83",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_order_line_quantity",
+ "original_column_name": "platform_reported_order_line_quantity",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed order line item quantity from the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28",
+ "column_sample_min": "0",
+ "column_sample_max": "190",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_unique_opens",
+ "original_column_name": "message_unique_opens",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique opens.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1104",
+ "column_sample_min": "0",
+ "column_sample_max": "61544",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_unique_clicks",
+ "original_column_name": "message_unique_clicks",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique clicks.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "213",
+ "column_sample_min": "0",
+ "column_sample_max": "1933",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "list_unsubscribes",
+ "original_column_name": "list_unsubscribes",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of list unsubscribe events attributed to the message.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "81",
+ "column_sample_min": "0",
+ "column_sample_max": "814",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_orders",
+ "original_column_name": "platform_reported_orders",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed order conversions from the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "26",
+ "column_sample_min": "0",
+ "column_sample_max": "75",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_unique_bounces",
+ "original_column_name": "message_unique_bounces",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Count of unique bounces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "142",
+ "column_sample_min": "0",
+ "column_sample_max": "774",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "platform_reported_begin_checkouts",
+ "original_column_name": "platform_reported_begin_checkouts",
+ "data_type": "NUMERIC",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform-attributed begin checkout events from the message/day.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "true",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "39",
+ "column_sample_min": "0",
+ "column_sample_max": "99",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Platform-specific customer identifier from the source system. Links to the customer who owns this address. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "42964",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++oygjqva", "++//ladtyl", "++/bfhxibh", "++/ephfq8e", "++0wixgstj", "++0zca7udi", "++2pmlds9y", "++2qajcqah", "++2ypmap4c", "++3f7rb07a", "++3ofgbo9h", "++3yuf2kb+", "++4ajmgssa", "++4o8z/i3h", "++4r9kuxpj", "++5fwch7kg", "++5kqolf8p", "++5v3z67ng", "++6awlgicw", "++6c5yjnfi", "++6qkyjv/m", "++87fg1ine", "++8cfnrrrf", "++8vhgsbke", "++a/uxwxnq", "++ajz8ekv8", "++bioe+zfr", "++bptum8vc", "++bqtlg4fd", "++brqmxsac"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "43215",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++gy97hhl", "++/ig1wufg", "++/oys3ymy", "++/t3ivagm", "++0ys8prkj", "++0zmq02o0", "++14m2sxd2", "++1xydt8nd", "++2fhrcyos", "++2fl2evwe", "++2j7b1tb8", "++2ukk+eyo", "++3edon5z1", "++4cksd2o9", "++4datdb1c", "++5vp7svy1", "++6dlxbvsu", "++7arnsvpq", "++7ncr62ei", "++7vu940te", "++8mjezwhh", "++a4s8vnru", "++bhy07jhq", "++cbdgzxcy", "++cols7ohp", "++cqleynjg", "++cytrfifr", "++d1sqsweo", "++dsjyyape", "++e2p1my6n"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "address_id",
+ "original_column_name": "address_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The unique identifier for the address. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "16.066742918657066",
+ "column_distinct_count": "37491",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++f2csd78", "+++ly8hcdy", "+++qycdqbu", "++/bf93ec8", "++0c84tqis", "++0fovqzgn", "++0jjkcx+m", "++0kfzylee", "++2xq2qzss", "++3b61vqjb", "++44ogpvuj", "++45ebk3/s", "++4rz+05/7", "++54az8zmk", "++5zt5gu9k", "++6svk2yvq", "++6w0/mvs/", "++81ytqbtz", "++8msiuqw4", "++996l9ios", "++asv/lvxj", "++ax6fnvku", "++b1k3gsgf", "++b4rx+jzf", "++bgenjx+/", "++br0pmxg3", "++bygnm1k1", "++cimexsg6", "++ciobgnlv", "++dhbfptpe"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_street_address",
+ "original_column_name": "customer_street_address",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The customer\u0027s street address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "19.626462646264624",
+ "column_distinct_count": "35276",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/yg5+0sz", "++05hsjyz9", "++08tzqg7o", "++08ygwvoh", "++1ogmomjj", "++2adzwhm+", "++3xuvb8k0", "++4wslrthq", "++5+sslxig", "++5nhpz7an", "++5rcnztji", "++62w5ilpg", "++66ojm90y", "++6gecqabe", "++7k9pez7b", "++7to6uzgz", "++8el6mdpe", "++8owdrnsm", "++aruo6zw7", "++avsxi+pt", "++axzq3kx4", "++ayjk8ybs", "++bcgq0au2", "++bslxra5e", "++co62ssbs", "++d9mfqy+e", "++dscsk4ki", "++e4ljrobh", "++epfi2ze1", "++focxc7qm"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_customer_address_key",
+ "original_column_name": "sm_customer_address_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The unique address key created by SourceMedium that can be used to join address dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "44101",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++5hnpire", "+++6q6oplk", "+++jyilyyz", "+++wl83eyk", "++/o0rlerb", "++/rfm+ebz", "++/tri3ap2", "++07amwheq", "++0hp8ympy", "++0xrj76io", "++1++x4ogz", "++1oyfb8ta", "++1vyhskcx", "++1wmk/0l9", "++20qovbfi", "++2hgt/tz1", "++3nebdg0o", "++3urx/jd+", "++4kyzkyrv", "++6fcfwtpk", "++70qzuh8l", "++7xg/84is", "++7ynvduaw", "++8zomrpn6", "++aghkypvv", "++ambkezhk", "++at4bmes9", "++b97tbzah", "++bdj32w4e", "++bhd/fh4o"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_province",
+ "original_column_name": "customer_address_province",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The province, state, or district code of the customer\u0027s location.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "6.2808877706891906",
+ "column_distinct_count": "415",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+3cukctf5y", "+71isvuxym", "+8iecavea6", "+91mwegalh", "+fit3krm93", "+ggiakrxw3", "+mjrz7nru8", "+q9jjptidl", "+qkmhlf+ho", "+uy/mkab15", "/7a/p/yloq", "/8e8+6s/j9", "/forwn2/lx", "/gxpven0dg", "/iflumk3vl", "/ihcxkhzfq", "/j9iva1poa", "/qaigokxlq", "/thycvbvqp", "/vqudxnjmt", "02tlyfrck7", "07mixcx0b4", "085l+qworo", "0d0dljgjwp", "0gilerjw3k", "0lremkttam", "0qskamw9uo", "0qzpychlve", "0sxnzp2eam", "0v38kkvd7n"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_zip_code",
+ "original_column_name": "customer_address_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The postal code of the customer\u0027s location.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.6721636478327477",
+ "column_distinct_count": "16061",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", ",NC28012-6761", "-", "--", "-098VR", ".", "0", "00-339", "00-367", "00-443", "00-712", "00-845", "000", "0000", "00000", "000000", "0000000", "00000000", "000002", "00006", "0001", "00010", "000105", "00012", "00013", "00019", "00030", "00040", "00041", "00042"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_city",
+ "original_column_name": "customer_address_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The city the customer\u0027s location is in. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.0148715637674628",
+ "column_distinct_count": "9829",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "\tNew Castle", " \tNew Castle", " Alexandria", " Ang Mo Kio,", " Beaver Falls", " Beaverton", " Bethesda", " Beverly Hills, ", " Bloomfield ", " Brentwood ", " Bronx", " Brussels", " CEDAR HILL", " Calgary ", " Cape Coral ", " Carmel", " Cebu City", " Chattanooga ", " Chino Hills", " Chino Valley", " Clearfield", " Clearwater", " Coalville", " Coatesville", " Coconut Creek ", " Colorado Springs", " Cork", " Covina", " Cross Plains"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_country",
+ "original_column_name": "customer_address_country",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The country the customer\u0027s location is in. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.18152074042534119",
+ "column_distinct_count": "105",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AE", "AF", "AG", "AL", "AO", "AR", "AT", "AU", "AW", "AZ", "American Samoa", "Australia", "Austria", "BB", "BD", "BE", "BG", "BH", "BM", "BO", "BR", "BS", "BT", "BZ", "Bahrain", "Belgium", "Brazil", "Bulgaria", "CA", "CH"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_country_code",
+ "original_column_name": "customer_address_country_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The two-letter code (ISO 3166-1 format) for the country of the customer\u0027s location. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.18921902101682697",
+ "column_distinct_count": "85",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AE", "AF", "AG", "AL", "AO", "AR", "AS", "AT", "AU", "AW", "AZ", "BB", "BD", "BE", "BG", "BH", "BM", "BO", "BR", "BS", "BT", "BZ", "CA", "CH", "CL", "CN", "CO", "CR", "CU", "CW"]
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_address_province_code",
+ "original_column_name": "customer_address_province_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The province, state, or district code (ISO 3166-2 alpha-2 format) of the customer\u0027s location. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "22.497369187022816",
+ "column_distinct_count": "214",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+8e4rmjaa4", "+9dnywskh4", "+fvd9o9trs", "+jt5e/s8ty", "+mddhqga4g", "+oxroucqb/", "+qhb86tjnx", "+s7m3ytjul", "/57j98t66f", "/bqgtzy+jc", "/cm9un0idl", "/ihcxkhzfq", "/o7hw7htj6", "/rhgkfmgeo", "/thycvbvqp", "07mixcx0b4", "0w1km/y1fy", "0yoptkg8pe", "1gxgu6lnm5", "1olwzqz6x3", "1tnnl8oaei", "218acfpewg", "2gibynedzt", "2ms3hh9vii", "2wusggy4xv", "335w5qivrp", "36umvzu5fg", "3hlaomzyl7", "3huu4sz/wd", "3knbt3tmzv"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "The ID of the customer who placed the order.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "90697",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++aotws0q", "+++kwzxqje", "+++obe5or2", "+++oygjqva", "+++vc5jh+8", "+++z2m4hz4", "++//ladtyl", "++/4eczdec", "++/ephfq8e", "++/sw6rf1/", "++03p1h9d1", "++0ut81wbd", "++0wixgstj", "++0zca7udi", "++18jy5m9z", "++1itiwxoy", "++2p3gidnp", "++2xzj6doa", "++2ypmap4c", "++30yfw4bu", "++3ofgbo9h", "++3sxfggys", "++3tshcdaw", "++4ajmgssa", "++4wtkhssm", "++5+cdjg7k", "++5+s/a99d", "++5kqolf8p", "++5sp0ujz2", "++5syemwg2"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "91258",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++6zhuhay", "+++a+ijdbn", "+++cb8c5k5", "+++g/9lwau", "+++gy97hhl", "+++j15bj8n", "++/2owaa+a", "++/t3ivagm", "++0hsywyta", "++0ys8prkj", "++14m2sxd2", "++1ke1ua/w", "++1xydt8nd", "++29d9tf2w", "++2fhrcyos", "++2fl2evwe", "++2oh6icyp", "++3kivwhbl", "++3zzz8vt5", "++4cksd2o9", "++4datdb1c", "++4ili/u+z", "++4kezz9jk", "++4kmhzi7g", "++4y4+eau/", "++5hjmlyng", "++5o24zoi7", "++5vp7svy1", "++5yo1oq4r", "++6dlxbvsu"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_first_name",
+ "original_column_name": "customer_first_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Customer\u0027s first name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.57117500887469",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_email_hashed",
+ "original_column_name": "customer_email_hashed",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "SHA-256 hash of customer email address. Used for privacy-safe customer matching and analytics across systems without exposing PII.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.2099926233388749",
+ "column_distinct_count": "89440",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++ETk2SaovO+NzO92Ar+Os7CX+xiy8PT5TA4MIww54\u003d", "+++mHQQQI2nQ6iaOyjp9ptHXJNDswje7Lufvl/NkF4I\u003d", "+++xJ/4a8vmayeB53WHCJeTse9AsvlWxG6TlGnbbRN4\u003d", "++/euVoIcwG3E/1QoWYlLXj05U0pS973N/Z54bvuKsI\u003d", "++095Y26PZ5/cELKdEvwlqKqf8MxJp9AI5DD9TOFN9w\u003d", "++0CAJXn4nyuCvXquMaAcqCtnQkX5OHFE0ri3PbEmcs\u003d", "++0xzWhb9hFDwEYUpsi1SylJtteQ/3jd63xeDq9AwA0\u003d", "++113Avb8EqnawoWRClwFaVj9FSKmwNz84yssORIYL0\u003d", "++1WKQBK3urm/S4RbY65OErwDApRz1X7NjMrr7nUG8I\u003d", "++1eYVnLZQ7Z8eCTeWj7/2O89f7yzp1jWJV7giP90pQ\u003d", "++1h2Vpefyk+F2g9F9tN0zPNYb5BQIJwkJcpDL8WVbY\u003d", "++1zEAs3Ie7mUyngCYZt0WIPChHuck3vyvpVCDpQ8Yw\u003d", "++24vdZQUXGmIkbcxf1PsaTSESMQPnFHJxXegKwsA08\u003d", "++2tpwg4SgwI3SiN9Te6M0aec/MbvvxEPkEIpKFFZDU\u003d", "++356k1I9MDkoC99R+TCig5VdGUAqTFa6XmDltBvpCw\u003d", "++3JYJUZ2p9u9HZM1uYXhTPmT7omNsPIXBzPBrXyiOk\u003d", "++3dRxFMYYpBenrnuA8k8zAerVLX4YlvH6WMNBHRq5M\u003d", "++3mNMqtt1ZDHMVeeB/Sf2+3U2hqyth07G/k2BxfOPQ\u003d", "++3mj59hala6pmtXtUQdV1QR0CfY70D3d85ZbwvnDUE\u003d", "++3nRHomg2DZlUxWbwnfgVw31rACXaa1u2mmDkAuieQ\u003d", "++4Bo7Vv5zZd6xJYeEB1mwe79yeSRxv/LQTc+GWl+yw\u003d", "++4C2mLz7q1xc+BalftlxpRHS+uPXoT93+K47izNJqc\u003d", "++59dWW44BBeKz0L94qKthO3/u8pkFyg8+jhEloyvM4\u003d", "++5f3Qau4V0eiH41mdJ49ucGBqlH8KAoFRCZO5FH4k8\u003d", "++5xTnzYl4jYIb2nnjfkDpG2HrBJNoEjJSKJUK3EA5c\u003d", "++60aygeLxASaaBr0lPi5dg9MQqjAjZhRnSQSDgf9w0\u003d", "++621n2F5KjUoTpQUhqpe9tyKZEmQs2A8kgRZ04WkJs\u003d", "++6UrGGc6tAxh7aMI/aAiHfe1AX31lCCAP/RNw5lv4k\u003d", "++6rMX0UFN2aPG4xBilxbmULvo3LhK2WDKxXFwYa0tA\u003d", "++7Epp4uY4nIro7XnwpNRE2eSbk3LsVTuQLNwuofXSQ\u003d"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_last_name",
+ "original_column_name": "customer_last_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Customer\u0027s last name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.745473071002181",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_phone_number",
+ "original_column_name": "customer_phone_number",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Customer\u0027s phone number in platform-provided format (varies by source_system). May be NULL if not collected; formatting and country codes not standardized. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "70.651646752788679",
+ "column_distinct_count": "26539",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++5kdpbs", "+++0eekeqb", "+++9mf+p1x", "+++ntpw4wy", "+++udwmxfl", "++/jynseyx", "++1i74h/za", "++1zborgmg", "++2enui81i", "++2nn+8zbd", "++50py1q24", "++5fxbrtec", "++5yptogrv", "++66wdnk2r", "++6a5bndo/", "++6eoggewp", "++a/vrf8pc", "++bbs0lbj8", "++bt8pucpu", "++cnohc/sv", "++cpj2ashi", "++ddiwrpgr", "++dsa5vrpg", "++dyi6kfmw", "++egxwqtcf", "++eoqnkfq9", "++fl3ayizy", "++flw2fofj", "++ftfa7xu+", "++gzthv2qj"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_tags_csv",
+ "original_column_name": "customer_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Comma-separated list of all tags associated with a customer. Use for simple filtering; beware that individual tag values may contain commas.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "86.541867776646157",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_email",
+ "original_column_name": "customer_email",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "Customer email address (PII); see customer_email_hashed for privacy‑safe matching.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.1367398741860721",
+ "column_distinct_count": "90535",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++et@example.com", "+++mh@example.com", "+++xj@example.com", "++/eu@example.com", "++095@example.com", "++0ca@example.com", "++0xz@example.com", "++113@example.com", "++1ey@example.com", "++1h2@example.com", "++1wk@example.com", "++1ze@example.com", "++24v@example.com", "++2tp@example.com", "++356@example.com", "++3dr@example.com", "++3jy@example.com", "++3mj@example.com", "++3mn@example.com", "++3nr@example.com", "++4bo@example.com", "++4c2@example.com", "++59d@example.com", "++5f3@example.com", "++5xt@example.com", "++60a@example.com", "++621@example.com", "++6rm@example.com", "++6ur@example.com", "++7ep@example.com"]
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "67271",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++1ne8ts5+", "++22nj24rc", "++2ku8gytz", "++36nb+zit", "++41w+pjmh", "++4oywszpx", "++5yoebovf", "++69bzaknm", "++6filyhzx", "++6h5v8oah", "++7mmnj5nc", "++7pzp3keo", "++8yfuxzom", "++aaiqewlf", "++adj+fbqm", "++aw5biowv", "++b/ahw5de", "++ccj+fzx1", "++cxcvsn2z", "++cxmmdbaf", "++d2duvfwd", "++ebij8fbc", "++egxspnvg", "++ezqf6585", "++f9czcyf9", "++fbhty6ci"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "discount_code",
+ "original_column_name": "discount_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The case-insensitive discount code that customers use at checkout. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.6675588497700908",
+ "column_distinct_count": "50",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ANNIVERSARY25", "BFCM60", "BIRTHDAY15", "BUNDLE25", "CLEARANCE40", "CLUB25", "COMEBACK20", "CYBER50", "DELUXE35", "DIAMOND50", "EARLY20", "ELITE25", "EMAIL15", "EXCLUSIVE35", "FALL30", "FIRST10", "FLASH25", "FREESHIP", "GOLD20", "HOLIDAY50", "INSIDER30", "LAUNCH25", "LIMITED50", "LOYALTY15", "MEGA60", "MEMBER20", "MOBILE10", "NEWCUSTOMER25", "NEWYEAR20", "PLATINUM35"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "discount_line_entity",
+ "original_column_name": "discount_line_entity",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The entity that the discount is applied to, such as an order line or a shipping line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["dabiz2oxnp", "put+luwc5a"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "discount_type",
+ "original_column_name": "discount_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The type of discount, such as an automatic discount, a discount code, or a manual discount. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "13.97420063126115",
+ "column_distinct_count": "34",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["15% OFF - LIMITED TIME OFFER", "20% OFF - LIMITED TIME OFFER", "25% OFF - LIMITED TIME OFFER", "50% OFF - LIMITED TIME OFFER", "Add-on Discount", "Bundling Discount", "Discount", "EARLY BIRD FREE GIFT", "ELITE KIT", "ELITE100", "Elite Bundle", "FACEMASK KIT", "FACEMASK100", "FREE - BLACK FRIDAY SPECIAL", "FREE - Black Friday Sale", "FREE - CYBER MONDAY SPECIAL", "FREE - CYBER WEEK SPECIAL", "FREE - HOLIDAY SPECIAL", "FREE - LIMITED TIME OFFER", "FREE - Labor Day Sale", "FREE - SPRING SPECIAL", "FREE GIFT", "FREE Shampoo", "FREE WITH BUNDLE", "Free Gift", "Free Max Growth Bundle with Pro Purchase", "Free Shipping", "Free With Laser System Purchase", "Kit Discount", "LIMITED TIME OFFER"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "73096",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++3expmju", "+++erecz/n", "+++polprfj", "+++udv63bv", "+++zi4t0dg", "++/1odfshe", "++/6sng+ml", "++/vuz4nk7", "++/zjlgmls", "++13okxajq", "++20lbzkor", "++2hq6ce3f", "++2kntr+8x", "++2togz+d2", "++30nbvgwm", "++312ujfin", "++356anh6a", "++375xifqg", "++3uy/uzek", "++3ynixql1", "++44g1dn1m", "++4ys+mfdh", "++51vzubwk", "++5ehyyrcf", "++5gdzx9pu", "++5o3fpy4x", "++6atjzawd", "++6kkokmtc", "++8cqert4v", "++8h86nmoe"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_discount_key",
+ "original_column_name": "sm_order_discount_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The unique discount key created by SourceMedium that can be used to join discount dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "73331",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++9rxzdln", "+++jwbaugx", "+++k1tuxq5", "+++o+e2v5o", "+++z3debjo", "++/5a6lldr", "++/8kxbkd1", "++/fzgw9wv", "++/homcauf", "++/ogrwex1", "++/pjidrms", "++0odeysff", "++0wuzp03l", "++1wgdbqmo", "++2kcq/4r3", "++2o4awnmb", "++2q7v/f35", "++2zsqbvbk", "++3/dqnhpi", "++32idmdwg", "++3aq3s0nx", "++3uehdlar", "++4caaarn7", "++4woatpyd", "++4yhb29nj", "++5/qllqy9", "++58teh/ln", "++5dzttk1c", "++5gmhyoy7", "++5no8tnos"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.4203527666355294",
+ "column_distinct_count": "72326",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++q9jlfd", "++/+lzj7g5", "++/grsjge2", "++/pzvcwxi", "++/t9ggrnr", "++02/q2p8g", "++04libdlc", "++0b7vdprh", "++1j9xr9yr", "++1u+vo7s9", "++1vhcas/q", "++2mk0eh1q", "++39zjilb+", "++3ia1rngj", "++3qa2mtg3", "++4dhh9k1e", "++4leccgjx", "++4nf8ksft", "++52guenwd", "++5hudv9mb", "++5v2qhsqx", "++5wcis5w2", "++6pzemziv", "++6zmgutuj", "++8/ktrqhw", "++8jrdpkiz", "++8kka1bqd", "++8m74vpgb", "++8nbippia", "++9/vrb4bm"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_currency_code",
+ "original_column_name": "order_currency_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The three-letter code (ISO 4217 format) for the currency used for the tender transaction. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["CAD", "USD"]
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "67501",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++0mnh6hs", "++/zscdnya", "++0ebf0e+m", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++4j4h1gve", "++4jmvzdmt", "++5d6l+cbg", "++6353iqcq", "++6qzsedjz", "++6uqo0c9h", "++6vbygukj", "++8yrbyxu+", "++acv2ibby", "++alnmb8pg", "++altzimal", "++b4eslapi", "++bmyq185z", "++brtu7f7n", "++c2ow8wyr", "++d+fg11hi", "++dskp/rkm", "++ebg5gqrl", "++endd6yzp", "++etru0juw", "++fccvbxsp", "++fx6diegr", "++gqwixek1", "++h7/uf2a3"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+++3expmju", "+++erecz/n", "+++fpw8agh", "+++r4xn4vr", "+++udv63bv", "+++zi4t0dg", "++/1odfshe", "++/6sng+ml", "++/awi1alo", "++/qwk3b/d", "++/sl7i6sw", "++/vuz4nk7", "++/zjlgmls", "++0iy+up4n", "++13okxajq", "++20lbzkor", "++2mgekdf8", "++2nu/uwfz", "++2togz+d2", "++2ulevlrb", "++2xjqoznp", "++3/ndwrw0", "++312ujfin", "++31cywq80", "++31qrnsef", "++356anh6a", "++375xifqg", "++3uy/uzek", "++3x/yoeip", "++43ziv09e"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_id",
+ "original_column_name": "product_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Platform-specific product identifier from the source system. Links to the parent product that this line item\u0027s variant belongs to.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+4umcswjrz", "+ayl/cffb9", "+hjvv9wv2r", "+pcwjo3bgx", "/3keuvyoh5", "/aoiqmpl4c", "02nhufsmzw", "060alpbt/d", "0jkrnpzzhh", "0omxvxywvc", "1laiofzdnm", "2ii9xq/ksm", "2my9nuqsrr", "2ue0aftlju", "3hvyz5rfeq", "3jvchbz95k", "49bqbhyfak", "4afi1gloor", "4lqezglqe6", "5fexbhp7tu", "5m96p5cram", "5o7yp8et/r", "6bnvut5frm", "6fhhfh8dlr", "6lbuxlrt3f", "6wy6hl3h1j", "7ghps1kvac", "7h2z4d8t5+", "7oj4q/e8ru", "7pwdh8bwvl"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+++wy9li0f", "++/erbc/ey", "++/goj85ge", "++/grsjge2", "++04libdlc", "++0b7vdprh", "++16esgrrd", "++1u+vo7s9", "++1vhcas/q", "++22lkc94i", "++39zjilb+", "++3ia1rngj", "++3qa2mtg3", "++4dhh9k1e", "++4nf8ksft", "++4nhchz3e", "++52guenwd", "++5c47e3+m", "++5hudv9mb", "++5v2qhsqx", "++5wcis5w2", "++6pzemziv", "++6zmgutuj", "++8/ktrqhw", "++8jrdpkiz", "++8kka1bqd", "++8nbippia", "++9/vrb4bm", "++9hwlowsz", "++9ks/ebxv"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sku",
+ "original_column_name": "sku",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The stock keeping unit (SKU) of the product variant.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+/O", "+1B", "+DP", "+OK", "+OY", "+QC", "+RG", "/4T", "/AK", "/HH", "/Y2", "0FJ", "0GB", "0I8", "0S4", "1/9", "10M", "1DC", "1K8", "1MP", "2MT", "2SF", "2TT", "2VV", "2YX", "38X", "3P3", "47D", "49Z", "4ED"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_id",
+ "original_column_name": "product_variant_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A unique identifier for the product variant generated by the source system.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+g+qhqdhpc", "+hdftijl+d", "+hzjugwrwi", "+mxm7hleyd", "+pon+pjshu", "+z/xboipjw", "/1plf3sxqf", "/4spnrzbwk", "/nsix4n8g5", "/pcso+1kho", "/zetfpit+c", "0e1kabxb1x", "0o54flbcpb", "0rfc/6ilnv", "1/cg+11/p6", "1/iroucw6d", "16ktskp696", "1kdz5jmrsk", "2/rxorh4xe", "29txzmjwiq", "2ekyw0dhev", "2k2tmlmyfh", "2wphqzwggs", "37ovr8gk4t", "3e0hc8c6vi", "3m8w8faggy", "3san9gxbni", "3sxjuc+93a", "41ywfvgagp", "4adq1e8kkm"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_product_variant_key",
+ "original_column_name": "sm_product_variant_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium join key for product variants to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+asq4bpdvr", "+meofze43+", "+tghb0qghr", "+ukxyxavka", "+zmz2brors", "/dbhwkefd2", "/j2dm7vkwg", "/j8kw5cyid", "/ocellizsq", "/xmwtvsoqw", "06kc4/ufen", "0dwdz721fh", "0zpmbpdgum", "18w1xxbypo", "1h3qx7jfvk", "1l4iahpo2a", "1lpgcn5w+i", "1t2q7e2o4v", "26yxndo4gq", "2okmsovktk", "2twurv48ma", "2vzixokyiv", "3cgu3dfczf", "3niju+ygvm", "3xmaoezxh8", "4bafl7sv/n", "4rpfju6+zs", "4rxwjdadvm", "4rzqcmjxd3", "4vdmy9j+i1"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_product_key",
+ "original_column_name": "sm_product_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium join key for products to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+5o862alaw", "+js4auzz35", "+qxhmmbb0o", "+uap7rlfws", "+uggjup17z", "+vsoj681mh", "/jmacfvzbq", "/nky7wavyh", "05k2sowe4q", "12lhc2qtbd", "1bpzc9ykyx", "1mebfzpwjh", "1oaowvsflu", "1q88himmhx", "21vlmj5dzi", "222zfuutd7", "2d+myxugyr", "2fldoea5xs", "2seiwbg/ly", "36lr3gz8fz", "3hfziqieun", "3l8idoxkye", "3pkoke/cta", "3qgp7bhrfp", "3wpnxowgij", "42klcdxlel", "4cgcfa71wr", "4iheehdtyk", "4lln6ucqvt", "5hxm7s8vou"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_product_variant_title",
+ "original_column_name": "order_line_product_variant_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The title of the product variant that the order line represents. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["2X-Large / Black", "2X-Large / Gray", "2X-Large / White", "3X-Large / Black", "3X-Large / Gray", "3X-Large / White", "Extra Small / Black", "Extra Small / Blue", "Extra Small / White", "Large / Blue", "Large / Bronze", "Large / Gold", "Large / Green", "Large / Navy", "Large / Pink", "Large / Red", "Large / Silver", "Large / White", "Medium / Black", "Medium / Blue", "Medium / Bronze", "Medium / Gold", "Medium / Gray", "Medium / Green", "Medium / Navy", "Medium / Pink", "Medium / Red", "Medium / Silver", "Medium / White", "One Size / Black"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_product_title",
+ "original_column_name": "order_line_product_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The title of the product variant that the order line represents. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["Advanced Formula", "Advanced Kit", "Advanced Set", "Basic Set", "Basic Unit", "Classic Edition", "Classic Set", "Combo Pack", "Combo Set", "Complete Bundle", "Complete System", "Deluxe Bundle", "Deluxe Edition", "Elite Bundle", "Elite Series", "Enhanced Kit", "Enhanced Version", "Essential Bundle", "Essential Collection", "Essential Product", "Exclusive Edition", "Exclusive Set", "Full Package", "Full Set", "Luxury Collection", "Master Collection", "Master Set", "Mega Bundle", "Mega Collection", "Original Bundle"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order line dimension for product-level attributes at line grain. Grain: One row per sm_order_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific line-item coverage. Key joins: dim_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": ["+++0mnh6hs", "+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0ebf0e+m", "++0jv1ijmb", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++3c/x09gr", "++47ptsa/a", "++49mmjnhl", "++4j4h1gve", "++4jmvzdmt", "++5nhbevun", "++5tcx/ala", "++6353iqcq", "++6qzsedjz", "++6uqo0c9h", "++6vbygukj", "++70r/osc4", "++8fwhn0o8", "++8naarfnp", "++8yrbyxu+", "++a1mdenkf", "++acv2ibby"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_line_id",
+ "original_column_name": "order_shipping_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "The ID that represents the shipping details for a customer\u0027s order. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64680",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++q9jlfd", "+++gnpndud", "+++tkhlkap", "+++wy9li0f", "++/bc1x1sq", "++/zjvbhvh", "++0gkva4fh", "++16esgrrd", "++1eviq9uv", "++1l+24qyv", "++1u+vo7s9", "++1yumxml+", "++217srdt5", "++2f5p2hmv", "++2q/hnsv1", "++3cevxd5e", "++3jcrdwex", "++3qzzmwvm", "++3tv38ezd", "++4erng+fq", "++4nf8ksft", "++4qxvzxdy", "++4rga4gjs", "++5vevlpz3", "++65pkuqav", "++6g2/qzam", "++7j5ze18f", "++8jrdpkiz", "++8kka1bqd", "++8m74vpgb"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "63750",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++fpw8agh", "+++r4xn4vr", "++/awi1alo", "++/d75odsa", "++/eqkgksx", "++/sl7i6sw", "++/vuz4nk7", "++0iy+up4n", "++29ozw5dt", "++2hq6ce3f", "++2ju2krgm", "++2kntr+8x", "++2nu/uwfz", "++2togz+d2", "++2ulevlrb", "++2xjqoznp", "++30nbvgwm", "++31cywq80", "++31qrnsef", "++3uy/uzek", "++3x/yoeip", "++44g1dn1m", "++4dt22zir", "++4kd211vm", "++4xbdnzfe", "++5e5ptpjz", "++5o3fpy4x", "++6kkokmtc", "++6ltsld3i", "++6ykqazx4"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64198",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/52lr43n", "++/nk0i+hs", "++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++19iaug1g", "++1ne8ts5+", "++1oscu3i5", "++1rane76v", "++1zslweke", "++22nj24rc", "++2ku8gytz", "++2xxjjoex", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++5yoebovf", "++69bzaknm", "++6h5v8oah", "++7/baoxfj", "++77akmh1u", "++7iv1sads", "++7jzxicxm", "++7pzp3keo", "++8dasxxmt", "++8yfuxzom", "++aaiqewlf"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64024",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0ebf0e+m", "++0jv1ijmb", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++3c/x09gr", "++47ptsa/a", "++49mmjnhl", "++4j4h1gve", "++4jmvzdmt", "++5d6l+cbg", "++5nhbevun", "++5tcx/ala", "++6353iqcq", "++6qzsedjz", "++6vbygukj", "++70r/osc4", "++8fwhn0o8", "++8naarfnp", "++8yrbyxu+", "++a1mdenkf", "++acv2ibby", "++ad66xtkv"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_shipping_line_key",
+ "original_column_name": "sm_shipping_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "The unique shipping line key created by SourceMedium that can be used to join shipping line dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64099",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++fpw8agh", "++/eqkgksx", "++/mcizur2", "++0sqvdqvs", "++1eta5sx9", "++2i7/yinx", "++2nu/uwfz", "++43yvpnjs", "++4dt22zir", "++5o3fpy4x", "++5zkhkvpw", "++6kkokmtc", "++6ltsld3i", "++6rnpox22", "++6ykqazx4", "++7wofxiaj", "++7y9lpw98", "++7zigllgg", "++8qnafzb6", "++9kbdxnqr", "++a6kkxv1w", "++ahajt2aj", "++alghtch1", "++ass/moie", "++axggtjd1", "++b6i5dxgs", "++bfhk1e9s", "++bolhcgtw", "++bplxy5uv", "++bwdcg7ym"]
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_line_title",
+ "original_column_name": "order_shipping_line_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "The title of the shipping line (e.g., 2-3 Day Shipping, Economy Shipping). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "37.4804053949186",
+ "column_distinct_count": "90",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+94ulmqihc", "+ebi3d1woi", "+ghnjjwfnt", "+qicty+7fg", "/tjbyirrcd", "05k40pslh/", "0fgorqqhy8", "0jb2sqxcbb", "0ldbpbiiwy", "0qav8f4y68", "0scsp7o0va", "0zyn2yxlzq", "1bfuonptzu", "1iroxhybxp", "1mf3rifaj8", "1xw1najv3m", "3fugfgttbv", "3rtdoogllm", "3wnoc6tags", "4+rku/tgv5", "49qq32k3ud", "4ey/miq16x", "4jd4f9zdgi", "4o/qjj0jtv", "4uymj74djl", "5nyqloj+5z", "5y5uxdpvqc", "6rmqirgatj", "6swiafn/ap", "7gbx0r1wwf"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_tax_key",
+ "original_column_name": "sm_order_tax_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The unique order tax key created by SourceMedium that can be used to join order tax dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "114463",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++ciqesoz", "+++dnanbj3", "+++mr4ryce", "+++o+e2v5o", "+++s7asl5q", "+++wfqzu0d", "+++z3debjo", "++/b60o/47", "++/ec0p6c3", "++/gliv/62", "++/rft78+l", "++/tdntezl", "++/uak6otq", "++/x04bbge", "++0/kaiuwa", "++00oibtdb", "++0xygkudt", "++13xon9kk", "++1rh0ttdf", "++1rmpuz1t", "++33ildg11", "++352sq5bo", "++3caqq7gx", "++3dubf38g", "++3ezupgec", "++3iyvn2h4", "++3qf1uvsk", "++3rzp5enj", "++3v6jjmcd", "++3yjy0fcf"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "tax_line_entity",
+ "original_column_name": "tax_line_entity",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The line the tax applies to (e.g., shipping, order). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["dabiz2oxnp", "put+luwc5a", "squ6p5fice"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_line_id",
+ "original_column_name": "order_shipping_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The ID of the shipping line. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.402935431075448",
+ "column_distinct_count": "1756",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++tkhlkap", "++mz4+2jos", "++pspqqxbb", "++pzau75k0", "++yyb/nodi", "+/4gknvvxj", "+/9rhnfec8", "+/of9tmbvi", "+/ouhd5n0q", "+/p2ddabx1", "+/wzxmcniw", "+0clnpndwq", "+0l4nmuury", "+0t04b05mk", "+0uxrb5uey", "+13sqezeqy", "+1av6jovbm", "+1bh2tbssk", "+1i1nzpthx", "+1scllccps", "+1xsqvncpg", "+2cr2bh8lo", "+2gate8rni", "+2vtkqrj4s", "+3btdlj59m", "+3q3dl4sc3", "+53foadu+3", "+577rc5e1g", "+5flcro3tr", "+5uwl+ej3u"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "tax_line_type",
+ "original_column_name": "tax_line_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The type of tax (e.g., state, county, excise and use, sales) applied to an order line. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "40.60188593262523",
+ "column_distinct_count": "921",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1200 MAIN SOUTH LOOP COMMUNITY IMPROVEMENT DISTRICT", "AIKEN CO CP", "AIKEN CO EDUCATION CAPITAL IMPROVEMENT TAX SD", "AL STATE TAX", "AL STATE TAX - ALABAMA", "ALAMEDA COUNTY DISTRICT TAX SP", "ALAMEDA Local Sales and Use Tax", "AMADOR COUNTY DISTRICT TAX SP", "ANOKA CO TR", "AR CITY TAX", "AR CITY TAX - ASHDOWN", "AR CITY TAX - BENTON", "AR CITY TAX - BENTONVILLE", "AR CITY TAX - BLYTHEVILLE", "AR CITY TAX - BRINKLEY", "AR CITY TAX - CABOT", "AR CITY TAX - CAVE SPRINGS", "AR CITY TAX - CENTERTON", "AR CITY TAX - CONWAY", "AR CITY TAX - ELM SPRINGS", "AR CITY TAX - EUREKA SPRINGS", "AR CITY TAX - FAYETTEVILLE", "AR CITY TAX - FORT SMITH", "AR CITY TAX - GLENWOOD", "AR CITY TAX - HAVANA", "AR CITY TAX - JACKSONVILLE", "AR CITY TAX - KEISER", "AR CITY TAX - LITTLE ROCK", "AR CITY TAX - MAUMELLE", "AR CITY TAX - MOUNTAIN HOME"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "101967",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0ebf0e+m", "++0jv1ijmb", "++1rq4thbq", "++47ptsa/a", "++4jmvzdmt", "++5nhbevun", "++5tcx/ala", "++6qzsedjz", "++6vbygukj", "++70r/osc4", "++8fwhn0o8", "++8naarfnp", "++acv2ibby", "++ad66xtkv", "++alnmb8pg", "++ankc4wyk", "++b3bs1py1", "++baehfrj1", "++bm3an32w", "++bmyq185z", "++brtu7f7n", "++bvlrb7mu", "++c2ow8wyr"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "101596",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/52lr43n", "++/nk0i+hs", "++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++1rane76v", "++1zslweke", "++2ku8gytz", "++2xxjjoex", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++5yoebovf", "++69bzaknm", "++7/baoxfj", "++77akmh1u", "++7iv1sads", "++7jzxicxm", "++7pzp3keo", "++8dasxxmt", "++8yfuxzom", "++aaiqewlf", "++acmf56kg", "++adj+fbqm", "++areiftnj", "++aw5biowv", "++aymz/upp", "++b/ahw5de"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.6138913686568994",
+ "column_distinct_count": "105036",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++q9jlfd", "+++wy9li0f", "++/+lzj7g5", "++/erbc/ey", "++/goj85ge", "++/pzvcwxi", "++/t9ggrnr", "++04libdlc", "++16esgrrd", "++1u+vo7s9", "++2f5p2hmv", "++39zjilb+", "++4leccgjx", "++4nf8ksft", "++4nhchz3e", "++52guenwd", "++5c47e3+m", "++5hudv9mb", "++5v2qhsqx", "++6zmgutuj", "++8/ktrqhw", "++8jrdpkiz", "++8kka1bqd", "++8m74vpgb", "++8nbippia", "++9/vrb4bm", "++9hwlowsz", "++9ks/ebxv", "++a+yntsp1", "++a/tsaanl"]
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "108699",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++dhwmsca", "+++erecz/n", "+++fpw8agh", "+++polprfj", "+++pp+mmwu", "++/1odfshe", "++/cceeiar", "++/eqkgksx", "++/qwk3b/d", "++/vuz4nk7", "++0iy+up4n", "++0rdgmzvw", "++0rnwqvit", "++1op7mygr", "++20lbzkor", "++2hq6ce3f", "++2kntr+8x", "++2mgekdf8", "++2nu/uwfz", "++2togz+d2", "++2ulevlrb", "++3/ndwrw0", "++30nbvgwm", "++375xifqg", "++3nzeakrn", "++3uy/uzek", "++3ynixql1", "++43ziv09e", "++44g1dn1m", "++4dt22zir"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_cancellation_reason",
+ "original_column_name": "order_cancellation_reason",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The customer\u0027s reason for the order\u0027s cancellation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.815457510307056",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["2smkengwc1", "8cuv7qsazk", "fwigzupadk", "ql+s87zxuw", "srqfspapcv", "tsryy4dene"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_payment_status",
+ "original_column_name": "order_payment_status",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Financial status of the order (e.g., paid, partially_paid, partially_refunded, authorized, pending, refunded, voided, draft). Platform‑defined.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["authorized", "paid", "partially_paid", "partially_refunded", "pending", "refunded", "voided"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_medium",
+ "original_column_name": "sm_utm_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Last-click UTM medium from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)", "cpc", "email", "organic", "paid_social", "sms"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "subscription_order_sequence",
+ "original_column_name": "subscription_order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Subscription lifecycle classification: \u0027First Subscription Order\u0027 for initial subscription purchase, \u0027Repeat Subscription Order\u0027 for renewals. Based on subscription order index when available, otherwise inferred from order tags. Use for subscription cohort analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_sub_order", "one_time_order", "recurring_sub_order"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_tags_csv",
+ "original_column_name": "order_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Comma-separated list of tags that the shop owner has attached to the order. Use for simple filtering; beware that individual tag values may contain commas.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "52.904294516518554",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "primary_order_payment_gateway",
+ "original_column_name": "primary_order_payment_gateway",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The technology or service that securely transmitted payment information between the customer, the business, and the payment processor. Special Considerations: For marketplaces (e.g., Amazon), gateway naming and presence may vary from direct-to-consumer platforms. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "7.27278299646015",
+ "column_distinct_count": "11",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affirm", "affirm_pay_over_time", "amazon_marketplace", "amazon_payments", "authorize_net", "bogus", "canal", "cash", "firstdata_e4", "gift_card", "manual", "paypal", "shop_cash", "shopify_installments", "shopify_payments", "tiktok_shop", "truemed"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_campaign",
+ "original_column_name": "sm_utm_campaign",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Last-click UTM campaign from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["acquisition_campaign", "anniversary_sale", "back_to_school", "brand_awareness", "bundle_promotion", "clearance_event", "customer_appreciation", "email_blast", "end_of_season", "fall_promo", "flash_sale", "holiday_campaign", "limited_time_offer", "loyalty_program", "mega_sale", "member_exclusive", "new_arrivals", "newsletter_promotion", "product_launch", "referral_campaign", "remarketing_push", "retargeting_ads", "retention_initiative", "seasonal_promo", "social_media_promo", "spring_launch", "summer_sale_2024", "weekend_special", "win_back", "winter_deals"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_customer_street_address",
+ "original_column_name": "order_customer_street_address",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Customer\u0027s billing street address associated with the order. May differ from shipping address; use for billing analysis and fraud detection. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "52.93632772403496",
+ "column_distinct_count": "28589",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++05hsjyz9", "++08tzqg7o", "++08ygwvoh", "++2adzwhm+", "++3xuvb8k0", "++4wslrthq", "++5+sslxig", "++5rcnztji", "++62w5ilpg", "++66ojm90y", "++6gecqabe", "++7k9pez7b", "++7to6uzgz", "++8el6mdpe", "++8owdrnsm", "++aruo6zw7", "++avsxi+pt", "++ayjk8ybs", "++bslxra5e", "++co62ssbs", "++dscsk4ki", "++focxc7qm", "++g/ca5gfz", "++golwh9ux", "++hehbboch", "++hv1tptq5", "++iay3ddrj", "++ivci6ame", "++jmkldktn", "++jo9b2edv"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_source",
+ "original_column_name": "sm_utm_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Last-click UTM source from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_referring_site",
+ "original_column_name": "order_referring_site",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The URL of the site that referred the customer to the shop.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.624005305039788",
+ "column_distinct_count": "328",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_term",
+ "original_column_name": "sm_utm_term",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Last-click UTM term from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1303",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++qq2wyzut", "+/zhh+87pe", "+0xweipll+", "+1yfkz2ry2", "+2e/uxp3ic", "+2mwhz0zcx", "+2vjnhcp7m", "+3+8mdkonj", "+5crhiqqzx", "+5db33syxo", "+abvlpzwr4", "+alfirsud9", "+bstbbitcu", "+co3l8mzq/", "+cumg0ommo", "+danbp82wr", "+f372ckaac", "+fewfkrtyg", "+fteybjxhk", "+gpkxy/xy/", "+hadikzfxt", "+hdgzzv+ap", "+hqrtt7ynv", "+ibmzinnck", "+imgrphhn3", "+itn6p07bh", "+ivnv8bsdf", "+j0uc75psp", "+jjniw1uiy", "+jk940dpx+"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_checkout_id",
+ "original_column_name": "order_checkout_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The ID of the checkout that the order is associated with.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "58.440709617180211",
+ "column_distinct_count": "26647",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qkxv4hx", "+++ssxtt4d", "++/+hirlad", "++0qpv/vxw", "++2k9bxemk", "++3yq16juh", "++4xnsmxkb", "++4xp+qetm", "++5+mqlo0y", "++5yagrqhd", "++7mhn0qbt", "++8hul48qs", "++aowibze0", "++blmh/xe/", "++emd/v3le", "++gkawndsc", "++gmlceren", "++gqoiul8w", "++hql+gcbv", "++hrop0gwx", "++isitjmnj", "++isy9g+qj", "++iuw0ob05", "++iwgvzceb", "++izklzzvu", "++jdw6yfzu", "++kfiud87a", "++kifipawd", "++la8qpbtu", "++lheowciz"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_number",
+ "original_column_name": "order_number",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Shop-scoped sequence number assigned by the platform. Not globally unique; pair with `smcid` for scoping.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "52.897363785270578",
+ "column_distinct_count": "30586",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++eh7ptr1", "++0222ysmx", "++0qx2tufq", "++1yiotovn", "++2mjzrcaj", "++2nmjdbui", "++3e1s4rxf", "++3s/weohj", "++4k5v4dcu", "++58dukgma", "++5pbzxypl", "++7jkxgdxw", "++7o1uphct", "++7qkzzla+", "++8cogucvg", "++8t6li0yz", "++8xepb62e", "++9vhvdm0q", "++cagir4ox", "++cqboyojp", "++d7hpwitv", "++ddfwsvi4", "++ddn1i4nx", "++diaf/pke", "++drz4tptm", "++dsptbtdc", "++eplvx1uu", "++etjtq+87", "++fcv54lvk", "++fkv9ujo9"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_referrer_domain",
+ "original_column_name": "sm_order_referrer_domain",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Domain derived from order_referring_site.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_country_code",
+ "original_column_name": "order_shipping_country_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The two-letter code (ISO 3166-1 format) for the country of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "75",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AD", "AE", "AL", "AR", "AS", "AT", "AU", "BB", "BD", "BE", "BG", "BH", "BM", "BR", "BS", "CA", "CH", "CL", "CN", "CO", "CR", "CU", "CW", "CY", "CZ", "DE", "DK", "EC", "EE", "EG"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_source_medium",
+ "original_column_name": "sm_utm_source_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Concatenation of source / medium (e.g., \u0027google / cpc\u0027). Shows \u0027(none) / (none)\u0027 when null.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct) / (none)", "google / cpc", "google / organic", "klaviyo / email", "klaviyo / sms", "meta / paid_social", "tiktok / paid_social"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_fbclid",
+ "original_column_name": "sm_fbclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Facebook Click Identifier (FBCLID) from Meta/Facebook ad campaigns, used to track social media conversions. Present when order originated from Facebook/Instagram ad click-through. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1230",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++catl0m0m", "+/0xcwlwsx", "+/2vfwqedj", "+/dh7cxdha", "+1dfxqcsrg", "+2lxyau6iv", "+2m3t1rhhd", "+3a4qylshp", "+3epu/ozt2", "+3tukwlrh1", "+3yqekxrm2", "+5ddqycyxw", "+5tuwdrub6", "+5tz+ve5d+", "+6+dxwa1p2", "+61zqn53cg", "+6auywl9hd", "+79hl6sqar", "+7l72fbyde", "+7p5dmgcvy", "+7pzntfxrr", "+7srovzlqj", "+83fvgktrm", "+8ec97/1ck", "+8viora5op", "+9cqutsbom", "+9ggnpwiuf", "+9phvedvf4", "+9vb3+tn2m", "+9zpkutgk5"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_processing_method",
+ "original_column_name": "order_processing_method",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The processing method used for the order (e.g., checkout, manual, express). Indicates how the order was created and processed in the source system. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "47.46701316379724",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon_payments"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_device_type",
+ "original_column_name": "customer_device_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Device type derived from user agent (e.g., mobile, desktop, tablet). Coverage depends on website tracking; limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "53.024152786201959",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Unknown", "desktop", "mobile", "tablet"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_source_name",
+ "original_column_name": "order_source_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Original source reported by the platform (e.g., Shopify sales channel/app name).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.316602958284861",
+ "column_distinct_count": "52",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_currency_code",
+ "original_column_name": "order_currency_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Three-letter ISO 4217 currency code for the order (e.g., USD, EUR, GBP). Used for multi-currency analysis and reporting. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["CAD", "USD"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Sales channel via hierarchy: (1) exclusion tag \u0027sm-exclude-order\u0027 -\u003e excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -\u003e retail, wholesale tags -\u003e wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_via_shopify", "draft_orders", "exchanged", "excluded", "online_dtc", "partners_/_affiliates", "retail", "wholesale"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_state",
+ "original_column_name": "order_shipping_state",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Province/state of the shipping address; format varies by country and platform.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.2173839193341673",
+ "column_distinct_count": "561",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", " Ave 10,", "-", "-1", ".", "0", "00", "117 E. Rodrigruez Jr. Ave Brgy Ugong", "722", "8 YEOUI-DAERO, YEONGDEUNGPO DISTRICT, SEOUL", "972", "A Coruña", "AA", "AB", "ACT", "AE", "AGUASCALIENTES", "AK", "AKERSHUS", "AL", "AL AHMEDI - ALI SUBAH AL SALEM", "AL.", "ALABAMA", "ALAJUELA", "ALASKA", "ALBERTA", "ALEXANDRIA", "ANGELES CITY", "ANT", "ANTIOQUIA"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_id",
+ "original_column_name": "sm_utm_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "SourceMedium-generated unique identifier for UTM parameter combinations on this order. Used to link orders to specific marketing campaigns via UTM tracking. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "247",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+26ojmerhn", "+albt6ppsb", "+an+n3egvi", "+bckoxwmwy", "+duhqx2hvh", "+fxs8nch1q", "+n4tlrhktj", "+oattuuzup", "+p+ffierdk", "+qftcfvwp+", "+qhjzuxygu", "+wqlqxczzm", "+yjtosstc3", "/1fjx0ertz", "/aqgk8rjdn", "/dhpvxg670", "/krr4oibag", "/lcjpzgwqi", "/lzuz3u3eb", "/nttnrecy0", "/setg/5nkv", "/tyahexl/a", "/uqgtaalo/", "/uwt+l03oy", "04pzwhua2i", "051mcfvyn/", "09dkt1jp+f", "0etdwuajqy", "0fd5ae06ev", "0gx7hcxu0w"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "65047",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/52lr43n", "++/nk0i+hs", "++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++19iaug1g", "++1ne8ts5+", "++1oscu3i5", "++1rane76v", "++1zslweke", "++22nj24rc", "++2ku8gytz", "++2xxjjoex", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++4oywszpx", "++5yoebovf", "++69bzaknm", "++6filyhzx", "++6h5v8oah", "++7/baoxfj", "++77akmh1u", "++7iv1sads", "++7jzxicxm", "++7mmnj5nc", "++7pzp3keo"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_sub_channel",
+ "original_column_name": "sm_sub_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Sub-channel from source/tags with config overrides (e.g., Facebook \u0026 Instagram, Google, Amazon FBA/Fulfilled by Merchant).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/tzi0a9fgc", "0vaq8ipxuc", "3tlnpaa4qx", "dw6kb6cabo", "et3l9c3ehk", "f3jc2brbra", "giref/lwrh", "gv24ockrwi", "kiyjjju7f5", "lw/tn577i9", "m5ruukjni1", "mybgqh7vvz", "mzse35tdre", "pgya+mnzxt", "sbwysv5ctz", "tiqlytmiee", "z6wtlvw+t8"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_vendors_csv",
+ "original_column_name": "order_vendors_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Comma-separated list of vendors associated with products in the order. Used for multi-vendor order analysis and vendor performance tracking. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "52.809179377245876",
+ "column_distinct_count": "10",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Alpha Distributors", "Apex Wholesale", "Epsilon Brands", "Gateway Trading", "Global Industries", "Junction Supply", "Meridian Corp", "Metro Wholesale", "Noble Suppliers", "Omega Distribution", "Standard Products", "Titan Wholesale", "Universal Brands", "Wholesale Direct", "Zeta Corporation"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Primary key (grain: one row per sm_order_key). Join to dim_order_lines via sm_order_key (1:many), dim_customers via sm_customer_key (many:1).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64898",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++0mnh6hs", "+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0ebf0e+m", "++0jv1ijmb", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++3c/x09gr", "++47ptsa/a", "++49mmjnhl", "++4j4h1gve", "++4jmvzdmt", "++5d6l+cbg", "++5nhbevun", "++5tcx/ala", "++6353iqcq", "++6qzsedjz", "++6uqo0c9h", "++6vbygukj", "++70r/osc4", "++8fwhn0o8", "++8naarfnp", "++8yrbyxu+", "++a1mdenkf"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_gclid",
+ "original_column_name": "sm_gclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Google Click Identifier (GCLID) from Google Ads campaigns, used to track paid search conversions. Present when order originated from Google Ads click-through. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1640",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++qogfezz9", "++taowu9r7", "+/hc2ebgnr", "+/jlakmpor", "+/l1wvpu6d", "+0fkhqit7v", "+0qmebua46", "+0von0kqtd", "+17wttuiqh", "+19f37whlb", "+1noudtotl", "+1o8gjkqw+", "+1pxglf7xo", "+1u62+u+fd", "+1uldn7uzs", "+244bematt", "+2nwysrkj5", "+2rnslmb9o", "+2wz4mvcht", "+2xe3ii6o8", "+3ftxn0a5r", "+3jcszj8yj", "+3k//5v0re", "+3tgjqw6fc", "+3vikb+owo", "+3wkx27cjb", "+4lavoeyqx", "+4obh1dn7f", "+5bd6ee7nt", "+5jo3ia3ud"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_utm_content",
+ "original_column_name": "sm_utm_content",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Last-click UTM content from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1499",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++6ps1hkc9", "++cbxa9g2s", "+/9q/q26sx", "+/xiq9mutb", "+03jakftzw", "+2apuj3fau", "+2mwhz0zcx", "+4m0ymx9sr", "+5bplhs4ib", "+5zdqbg5ys", "+6rkoxisfm", "+6y2amsubp", "+9ilkh/bwe", "+ajskfhtqb", "+arpfjskro", "+bxhtczyj1", "+cokok5inb", "+cumg0ommo", "+dzhpot+yl", "+e7hmjcaj/", "+eyz0scoxq", "+eyz6eef1a", "+fendzct2p", "+fno9wmjoe", "+frrvjx78d", "+fu6h1dgru", "+g8fvxl9bw", "+gerfb5ona", "+h/pwa6rq9", "+h3+6acvp+"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_city",
+ "original_column_name": "order_shipping_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The city, town, or village of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.35302861389817908",
+ "column_distinct_count": "12669",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "\tNew Castle", " \tNew Castle", " Alexandria", " Ang Mo Kio,", " Arlington", " Baldwin Park", " Beaver Falls", " Beaverton", " Beverly Hills, ", " Boca Raton", " Brentwood ", " Bronx", " Brooklyn ", " Brussels", " CLIFTON", " Cape Coral ", " Carmel", " Chantilly", " Chattanooga ", " Chestnut Hill", " Chino Hills", " Chino Valley", " Clearfield", " Clearwater", " Coalville", " Coatesville", " Coconut Creek ", " Colorado Springs", " Crestview, "]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The ID of the customer who placed the order.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "13.31617783840764",
+ "column_distinct_count": "49392",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++obe5or2", "+++oygjqva", "++//ladtyl", "++/bfhxibh", "++/ephfq8e", "++0odfm0z1", "++0wixgstj", "++18jy5m9z", "++2pmlds9y", "++2ypmap4c", "++3f7rb07a", "++3ofgbo9h", "++3yuf2kb+", "++4ajmgssa", "++4o8z/i3h", "++4r9kuxpj", "++5fwch7kg", "++5kqolf8p", "++5v3z67ng", "++6awlgicw", "++6c5yjnfi", "++6qkyjv/m", "++87fg1ine", "++8vhgsbke", "++a/uxwxnq", "++bptum8vc", "++brqmxsac", "++bswehump", "++bujah62n", "++c0jcazmw"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_sequence",
+ "original_column_name": "order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Customer lifecycle classification: \u0027First Order\u0027 for new customers, \u0027Repeat Order\u0027 for returning customers. Includes all orders (valid + invalid). Use for cohort analysis and retention reporting. See valid_order_index for valid-only ordering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_order", "repeat_order"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_landing_page",
+ "original_column_name": "sm_order_landing_page",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The URL for the page where the buyer landed when they entered the shop.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_default_channel",
+ "original_column_name": "sm_default_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Default channel before overrides, from source name and tags: amazon/tiktok_shop/walmart.com; pos/leap -\u003e retail; wholesale tags -\u003e wholesale; otherwise online_dtc. See sm_channel for final channel.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "9",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_multi_channel_fulfillment", "amazon_via_shopify", "draft_orders", "exchanged", "excluded", "online_dtc", "partners_/_affiliates", "retail", "wholesale"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_sales_channel",
+ "original_column_name": "sm_order_sales_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Raw sales channel from source system (e.g., \u0027TikTok Shop\u0027, \u0027Instagram Shop\u0027). Used as input dimension for sm_channel mapping. See sm_channel for final classification.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "18",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["aftersell", "amazon.ca", "amazon.com", "amazon_removal_order", "amazon_via_shopify", "canal", "draft_orders", "facebook_\u0026_instagram", "faire:_sell_wholesale", "gorgias", "grin_creator_management", "non_amazon", "non_amazon_ca", "non_amazon_us", "online_dtc", "online_store", "point_of_sale", "recharge", "shop_app", "shopify_app_ios", "si_ca_prod_marketplace", "subscription", "tiktok_shop"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_session_browser_type",
+ "original_column_name": "order_session_browser_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Browser type derived from user agent (e.g., chrome, safari, firefox). Coverage depends on website tracking; limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["android", "chrome", "firefox", "ie", "ipad_safari", "iphone_safari", "opera", "safari", "unknown"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to dim_customers (many:1 - multiple orders per customer). Special Considerations: Some platforms (e.g., TikTok Shop) may provide limited linkage, resulting in NULLs for certain orders.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "49099",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cb8c5k5", "+++eczts6a", "++/oys3ymy", "++0ys8prkj", "++0zmq02o0", "++14m2sxd2", "++1k648y7b", "++1xydt8nd", "++2fhrcyos", "++2j7b1tb8", "++2ukk+eyo", "++3edon5z1", "++4cksd2o9", "++4datdb1c", "++4y4+eau/", "++5vp7svy1", "++6cnyry9j", "++6dlxbvsu", "++7arnsvpq", "++7ncr62ei", "++7vqpsyow", "++7vu940te", "++86tihdhc", "++8mjezwhh", "++a4s8vnru", "++bhy07jhq", "++cbdgzxcy", "++cols7ohp", "++cytrfifr", "++d1sqsweo"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_zip_code",
+ "original_column_name": "order_shipping_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The postal code of the shipping address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.74858386454490733",
+ "column_distinct_count": "30813",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", " 78260", " 91401", "+051", "+852", "+973", "-", ".", "0", "00", "00-845", "000", "0000", "00000", "000000", "00004", "00012", "00013", "000157", "00019", "00040", "00041", "00042", "00043", "00045", "00052", "00060", "00063", "00071", "00072"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_session_user_agent",
+ "original_column_name": "order_session_user_agent",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Raw user agent string. Used to derive customer_device_type and order_session_browser_type.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "60.411715687787414",
+ "column_distinct_count": "6899",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "[fban/fbios;fbdv/ipad7,5;fbmd/ipad;fbsn/ios;fbsv/13.6.1;fbss/2;fbid/tablet;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone11,6;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone11,8;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/2;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,3;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,5;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,5;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/fr_fr;fbop/5]", "agent/amazonbuyforme", "go-http-client/2.0", "mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; slcc1; .net clr 2.0.50727; media center pc 5.0; .net clr 1.1.4322; .net clr 3.0.30618; .net clr 3.5.30729; infopath.2; .net4.0c)", "mozilla/5.0 (android 10; mobile; rv:100.0) gecko/100.0 firefox/100.0", "mozilla/5.0 (android 10; mobile; rv:109.0) gecko/119.0 firefox/119.0", "mozilla/5.0 (android 10; mobile; rv:121.0) gecko/121.0 firefox/121.0", "mozilla/5.0 (android 10; mobile; rv:129.0) gecko/129.0 firefox/129.0", "mozilla/5.0 (android 10; mobile; rv:67.0) gecko/67.0 firefox/67.0", "mozilla/5.0 (android 10; mobile; rv:68.0) gecko/68.0 firefox/68.0", "mozilla/5.0 (android 10; mobile; rv:71.0) gecko/71.0 firefox/71.0", "mozilla/5.0 (android 10; mobile; rv:75.0) gecko/75.0 firefox/75.0", "mozilla/5.0 (android 10; mobile; rv:80.0) gecko/80.0 firefox/80.0", "mozilla/5.0 (android 10; mobile; rv:81.0) gecko/81.0 firefox/81.0", "mozilla/5.0 (android 10; mobile; rv:82.0) gecko/82.0 firefox/82.0", "mozilla/5.0 (android 10; mobile; rv:83.0) gecko/83.0 firefox/83.0", "mozilla/5.0 (android 10; mobile; rv:84.0) gecko/84.0 firefox/84.0", "mozilla/5.0 (android 10; mobile; rv:86.0) gecko/86.0 firefox/86.0", "mozilla/5.0 (android 10; mobile; rv:87.0) gecko/87.0 firefox/87.0", "mozilla/5.0 (android 10; mobile; rv:88.0) gecko/88.0 firefox/88.0", "mozilla/5.0 (android 10; mobile; rv:89.0) gecko/89.0 firefox/89.0", "mozilla/5.0 (android 10; mobile; rv:90.0) gecko/90.0 firefox/90.0", "mozilla/5.0 (android 10; mobile; rv:99.0) gecko/99.0 firefox/99.0", "mozilla/5.0 (android 11; mobile; rv:100.0) gecko/100.0 firefox/100.0"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_shipping_country",
+ "original_column_name": "order_shipping_country",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "The country of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "75",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Albania", "American Samoa", "Andorra", "Argentina", "Australia", "Austria", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belgium", "Bermuda", "Brazil", "Bulgaria", "Cambodia", "Canada", "Cayman Islands", "Chile", "China", "Colombia", "Costa Rica", "Croatia", "Cuba", "Curaçao", "Cyprus", "Czech Republic", "Denmark", "Ecuador", "Egypt", "Estonia"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_order_type",
+ "original_column_name": "sm_order_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Skio, Loop, Retextion).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["one_time", "subscription", "subscription_\u0026_one_time"]
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_name",
+ "original_column_name": "order_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "Platform-rendered name (human‑readable or platform‑specific). Not a stable join key.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.2262269348558765",
+ "column_distinct_count": "64726",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cfjzsrf", "++/nk0i+hs", "++/y2j9abi", "++03jqfpbc", "++0i6e8zrt", "++19iaug1g", "++1klwkf0z", "++1zslweke", "++22nj24rc", "++2gvh2bxc", "++2ku8gytz", "++2xxjjoex", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++4vstvi1n", "++69bzaknm", "++6ltsxhs9", "++6r9dnc0t", "++7/baoxfj", "++77akmh1u", "++7ahc0sep", "++7jzxicxm", "++7k6eamy9", "++7pzp3keo", "++89i8mrxn", "++8dasxxmt", "++8ehtizzg"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_collection_titles_csv",
+ "original_column_name": "product_collection_titles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "53.333333333333336",
+ "column_distinct_count": "13",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Back in Stock", "Bestselling Bundles", "Classic Collection", "Clearance", "Customer Favorites", "Deluxe Collection", "Eco-Friendly", "Essential Sets", "Fall Collection", "Featured Products", "Full Size", "Gift Ideas", "Gift Sets", "Holiday Shop", "Made to Order", "Modern Line", "Premium Selection", "Professional Series", "Recently Added", "Sale Items", "Seasonal Collection", "Specialty Items", "Spring Collection", "Staff Picks", "Starter Kits", "Summer Collection", "Top Rated", "Travel Size", "Trending Now", "Value Bundles"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_collection_handles_csv",
+ "original_column_name": "product_collection_handles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Unique, human-readable strings for the collections a product belongs to automatically generated from their titles. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "52.72727272727272",
+ "column_distinct_count": "16",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["back-in-stock", "bestselling-bundles", "classic-collection", "clearance", "complete-kits", "deluxe-collection", "eco-friendly", "exclusive-releases", "fall-collection", "featured-products", "gift-sets", "limited-edition", "limited-stock", "made-to-order", "modern-line", "new-arrivals", "popular-choices", "premium-selection", "recently-added", "sale-items", "seasonal-collection", "specialty-items", "spring-collection", "staff-picks", "starter-kits", "summer-collection", "sustainable-products", "top-rated", "travel-size", "trending-now"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_id",
+ "original_column_name": "product_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "A unique identifier for the product generated by the source_system. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "42",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+4umcswjrz", "+ayl/cffb9", "+hjvv9wv2r", "+pcwjo3bgx", "/3keuvyoh5", "/aoiqmpl4c", "/ndj98sggs", "02nhufsmzw", "060alpbt/d", "0jkrnpzzhh", "0omxvxywvc", "1s2ktw466m", "1xwiyjp84z", "2ii9xq/ksm", "2my9nuqsrr", "2ue0aftlju", "3jvchbz95k", "49bqbhyfak", "4afi1gloor", "4aif2mssow", "4kupjsqhls", "4lqezglqe6", "5fexbhp7tu", "5m96p5cram", "5o7yp8et/r", "6bnvut5frm", "6fhhfh8dlr", "6wy6hl3h1j", "7ghps1kvac", "7h2z4d8t5+"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "marketplace_id",
+ "original_column_name": "marketplace_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Marketplace-specific identifier for the product variant when sold through third-party marketplaces (e.g., Amazon ASIN). NULL for direct-to-consumer sales; used to track marketplace product listings. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "84.210526315789465",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["d8aq2woo5r", "sty/05lm7v"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "primary_product_image",
+ "original_column_name": "primary_product_image",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Primary product image URL (display).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_title",
+ "original_column_name": "product_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The title of the product.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "37",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Advanced Formula", "Advanced Kit", "Advanced Set", "Basic Set", "Basic Unit", "Classic Edition", "Classic Set", "Combo Pack", "Combo Set", "Complete Bundle", "Complete System", "Deluxe Bundle", "Deluxe Edition", "Elite Bundle", "Elite Series", "Enhanced Kit", "Enhanced Version", "Essential Bundle", "Essential Collection", "Essential Product", "Exclusive Edition", "Exclusive Set", "Full Package", "Full Set", "Luxury Collection", "Master Collection", "Master Set", "Mega Bundle", "Mega Collection", "Original Bundle"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_id",
+ "original_column_name": "product_variant_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "A unique identifier for the product variant generated by the source system.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "43",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+e5a0qas+3", "+g+qhqdhpc", "+hdftijl+d", "+hzjugwrwi", "+mxm7hleyd", "+pon+pjshu", "+z/xboipjw", "/1plf3sxqf", "/4spnrzbwk", "/jkwfwznv9", "/nsix4n8g5", "/pcso+1kho", "/zetfpit+c", "0apz75k93f", "0e1kabxb1x", "0gpdwnwa6y", "0o54flbcpb", "0rfc/6ilnv", "1/cg+11/p6", "1/iroucw6d", "16ktskp696", "1kdz5jmrsk", "1n1mwqmkzh", "2/rxorh4xe", "29txzmjwiq", "2ekyw0dhev", "2k/ps965md", "2k2tmlmyfh", "2m58o8b3tk", "2wphqzwggs"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "inventory_item_id",
+ "original_column_name": "inventory_item_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The unique identifier for the inventory item. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "5.5555555555555554",
+ "column_distinct_count": "34",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+icawi8+m2", "+kt9ttigco", "+mx+xbrbh/", "+n2onsyvqs", "+rhudpelz8", "+z/xboipjw", "+zyvqujaco", "/c/zhf39a5", "/cfv6v5han", "/jtsnyr+vd", "/vvwzdhulg", "09ale67wlo", "0a56x7hrrl", "0e1kabxb1x", "11onhjjisv", "1ae1nr5i45", "1mket6dbbs", "1tti4u3nul", "26jchmfemz", "29txzmjwiq", "2eh1hgtbzq", "2fuuebdjvi", "2neb6a4+zy", "2ol7qipvjy", "2qyj0mzaym", "2wpuw5vioz", "31pu5zjmmq", "33x/c+mihe", "37sfrdv3ie", "3an16z+iav"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_vendor",
+ "original_column_name": "product_vendor",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The name of the vendor of the product. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "14.285714285714285",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Gateway Trading", "Global Industries", "Standard Products"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_tags_csv",
+ "original_column_name": "product_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Tags that the shop owner has attached to the product. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "13.513513513513514",
+ "column_distinct_count": "10",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "discount_user", "domestic", "email_subscriber", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_product_key",
+ "original_column_name": "sm_product_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Stable SourceMedium join key for products to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "39",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+c4o82mxw8", "+js4auzz35", "+qxhmmbb0o", "+uap7rlfws", "+uggjup17z", "+vsoj681mh", "/jmacfvzbq", "/nky7wavyh", "05k2sowe4q", "12lhc2qtbd", "1bpzc9ykyx", "1mebfzpwjh", "1oaowvsflu", "222zfuutd7", "2d+myxugyr", "2fldoea5xs", "2seiwbg/ly", "2wyqdoctyf", "36lr3gz8fz", "3deocrkk9m", "3f1qz+5gwp", "3hfziqieun", "3l8idoxkye", "3pkoke/cta", "3qgp7bhrfp", "3wpnxowgij", "42klcdxlel", "4cgcfa71wr", "4iheehdtyk", "5hxm7s8vou"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_type",
+ "original_column_name": "product_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "A categorization for the product used for filtering and searching for products.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "28.947368421052634",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Basic Unit", "Classic Edition", "Enhanced Kit", "Essential Collection", "Full Set", "Performance Kit", "Prime Package", "Standard Unit", "Superior Product"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sm_product_variant_key",
+ "original_column_name": "sm_product_variant_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "Stable SourceMedium join key for product variants to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "52",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+asq4bpdvr", "+meofze43+", "+tghb0qghr", "+ukxyxavka", "+zmz2brors", "/0lqdnqxrh", "/dbhwkefd2", "/j2dm7vkwg", "/j8kw5cyid", "/ocellizsq", "/xmwtvsoqw", "06kc4/ufen", "0dwdz721fh", "0hex7n3/dv", "0zpmbpdgum", "18w1xxbypo", "1ab1kkugot", "1h3qx7jfvk", "1l4iahpo2a", "1lpgcn5w+i", "1ma8g3k3/3", "1t2q7e2o4v", "26yxndo4gq", "2okmsovktk", "2twurv48ma", "2vgetzyhed", "2vzixokyiv", "33iwz/tgzx", "3cgu3dfczf", "3eyzpsntrc"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_title",
+ "original_column_name": "product_variant_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The title of the product variant.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "26",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["2X-Large / Black", "2X-Large / Gray", "2X-Large / White", "3X-Large / Black", "3X-Large / Gray", "3X-Large / White", "Extra Small / Black", "Extra Small / Blue", "Extra Small / White", "Large / Blue", "Large / Bronze", "Large / Gold", "Large / Green", "Large / Navy", "Large / Pink", "Large / Silver", "Medium / Black", "Medium / Blue", "Medium / Bronze", "Medium / Gold", "Medium / Gray", "Medium / Green", "Medium / Navy", "Medium / Pink", "Medium / Red", "Medium / Silver", "Medium / White", "One Size / Black", "One Size / Blue", "One Size / Gray"]
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "sku",
+ "original_column_name": "sku",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The stock keeping unit (SKU) of the product variant.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "35",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+/O", "+1B", "+DP", "+OK", "+OY", "+QC", "/1O", "/4T", "/AK", "/HH", "/UN", "0DY", "0EX", "0FJ", "0GB", "0I8", "0S4", "1/9", "10M", "1DC", "1K8", "1MP", "2MT", "2SF", "2TT", "2VV", "38X", "3P3", "47D", "49Z"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_product_variant_key",
+ "original_column_name": "sm_product_variant_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Stable SourceMedium join key for product variants to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "254",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+asq4bpdvr", "+meofze43+", "+ukxyxavka", "+zmz2brors", "/dbhwkefd2", "/j2dm7vkwg", "/j8kw5cyid", "/ocellizsq", "/xmwtvsoqw", "06kc4/ufen", "0dwdz721fh", "0zpmbpdgum", "18w1xxbypo", "1h3qx7jfvk", "1l4iahpo2a", "1lpgcn5w+i", "1ma8g3k3/3", "26yxndo4gq", "2okmsovktk", "2twurv48ma", "2vzixokyiv", "3cgu3dfczf", "3niju+ygvm", "3xmaoezxh8", "4bafl7sv/n", "4rpfju6+zs", "4rxwjdadvm", "4rzqcmjxd3", "4vdmy9j+i1", "4vswk67lay"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "58589",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++0mnh6hs", "+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++1hay6gzy", "++49mmjnhl", "++4j4h1gve", "++5d6l+cbg", "++6353iqcq", "++6qzsedjz", "++6vbygukj", "++8fwhn0o8", "++8yrbyxu+", "++a1mdenkf", "++ad66xtkv", "++alnmb8pg", "++altzimal", "++baehfrj1", "++bm3an32w", "++bmyq185z", "++brtu7f7n", "++bvlrb7mu", "++d+fg11hi", "++dijviqwh", "++ebg5gqrl", "++echb9aah", "++endd6yzp"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "60648",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++3expmju", "+++fpw8agh", "+++udv63bv", "++/1odfshe", "++/6sng+ml", "++/eqkgksx", "++/vuz4nk7", "++0iy+up4n", "++0rdgmzvw", "++20lbzkor", "++2hq6ce3f", "++2mgekdf8", "++2togz+d2", "++2ulevlrb", "++3/ndwrw0", "++30nbvgwm", "++3ynixql1", "++4dt22zir", "++51vzubwk", "++5ehyyrcf", "++5o3fpy4x", "++6kkokmtc", "++6qzsedjz", "++6ykqazx4", "++7wofxiaj", "++8cqert4v", "++8h86nmoe", "++90wladds", "++9aoyjmp+", "++a2gj0l39"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "product_variant_id",
+ "original_column_name": "product_variant_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "A unique identifier for the product variant generated by the source system.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.0986832322765048",
+ "column_distinct_count": "253",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+hdftijl+d", "+hzjugwrwi", "+mxm7hleyd", "+pon+pjshu", "+z/xboipjw", "/nsix4n8g5", "/pcso+1kho", "/zetfpit+c", "0apz75k93f", "0e1kabxb1x", "0o54flbcpb", "0rfc/6ilnv", "1/cg+11/p6", "1/iroucw6d", "16ktskp696", "1kdz5jmrsk", "1n1mwqmkzh", "2/rxorh4xe", "29txzmjwiq", "2ekyw0dhev", "2k2tmlmyfh", "2wphqzwggs", "37ovr8gk4t", "3e0hc8c6vi", "3m8w8faggy", "3san9gxbni", "3sxjuc+93a", "41ywfvgagp", "4adq1e8kkm", "4cnjlmnikl"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_product_key",
+ "original_column_name": "sm_product_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Stable SourceMedium join key for products to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "170",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+5o862alaw", "+js4auzz35", "+qxhmmbb0o", "+uap7rlfws", "+uggjup17z", "+vsoj681mh", "/jmacfvzbq", "/nky7wavyh", "05k2sowe4q", "12lhc2qtbd", "1bpzc9ykyx", "1mebfzpwjh", "1oaowvsflu", "1q88himmhx", "21vlmj5dzi", "222zfuutd7", "2d+myxugyr", "2fldoea5xs", "2seiwbg/ly", "36lr3gz8fz", "3deocrkk9m", "3f1qz+5gwp", "3hfziqieun", "3l8idoxkye", "3pkoke/cta", "3qgp7bhrfp", "3wpnxowgij", "42klcdxlel", "4cgcfa71wr", "4iheehdtyk"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "58630",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++1oscu3i5", "++2ku8gytz", "++3cilkyrs", "++3mhfe1vw", "++41w+pjmh", "++4oywszpx", "++5yoebovf", "++69bzaknm", "++6filyhzx", "++6h5v8oah", "++7iv1sads", "++7jzxicxm", "++7mmnj5nc", "++8yfuxzom", "++aaiqewlf", "++acmf56kg", "++adj+fbqm", "++areiftnj", "++aw5biowv", "++aymz/upp", "++b/ahw5de", "++bcuo1oce", "++bniszlnq", "++cei1wnh9", "++ckroortk", "++cxcvsn2z", "++cxmmdbaf"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016431693450326993",
+ "column_distinct_count": "48720",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cb8c5k5", "++0ys8prkj", "++0zmq02o0", "++14m2sxd2", "++1xydt8nd", "++2fhrcyos", "++2ukk+eyo", "++3edon5z1", "++4cksd2o9", "++4datdb1c", "++4y4+eau/", "++5vp7svy1", "++6cnyry9j", "++6dlxbvsu", "++7ncr62ei", "++7vqpsyow", "++7vu940te", "++8mjezwhh", "++a4s8vnru", "++bhy07jhq", "++cbdgzxcy", "++cols7ohp", "++d1sqsweo", "++do9jdn62", "++dsjyyape", "++e1htkvjd", "++e2p1my6n", "++fzbgen0b", "++gjsrdkwh", "++gquwnxus"]
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "61278",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++wy9li0f", "++/+lzj7g5", "++/erbc/ey", "++/grsjge2", "++02/q2p8g", "++04libdlc", "++16esgrrd", "++1j9xr9yr", "++1u+vo7s9", "++1vhcas/q", "++22lkc94i", "++2f5p2hmv", "++4leccgjx", "++4nf8ksft", "++4nhchz3e", "++52guenwd", "++5c47e3+m", "++5wcis5w2", "++9/vrb4bm", "++9vnrw024", "++a/tsaanl", "++afqui46d", "++awctapio", "++b86bizr3", "++c/+vesm/", "++caygvpj3", "++ccvvwb9m", "++cdt8yhcj", "++cjklahst", "++cq2bgbpd"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12069",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++3c/x09gr", "++acv2ibby", "++b4eslapi", "++bvlrb7mu", "++caqnuddo", "++d+fg11hi", "++mcpvktjo", "++mnwluikt", "++mwoayxbj", "++o7ls7xeu", "++ol+2ubcr", "++psbhk1h4", "++vkhcbfkt", "++vxug8wkd", "++xv8gp19r", "+/2b16kzcn", "+/3+ara8zd", "+/4/q1f8b8", "+/6fupbgpw", "+/7d439hx2", "+/cm6bpchh", "+/f6gbzxhr", "+/jvq8gi6s", "+/kcdwduii", "+/ktjcenww", "+/pbtctu6d", "+/xumtxylp", "+/zr2metd2", "+0/nxge3mf", "+01clkgxa3"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "11981",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++7/baoxfj", "++7iv1sads", "++7mmnj5nc", "++ccj+fzx1", "++cxcvsn2z", "++fgcg0ku9", "++g8hg/70k", "++kr8m1ry2", "++n5tkkta0", "++odc6osgx", "++r9zvlj/a", "++vbj8natf", "+/47zmbv5l", "+/8jqfcna5", "+/e8wfvbsq", "+/flobzua3", "+/oi9at/t3", "+/pb5n/hts", "+/pgnx+egb", "+/udcls94m", "+/uzokugcd", "+/zrhi6niz", "+083mqgwy8", "+0bgs10wcj", "+0gxc5rpeu", "+0gxxge2gj", "+0h5iz6ov0", "+0h7jbkslr", "+0jaeqw8uh", "+0lplkuqfi"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_product_key",
+ "original_column_name": "sm_product_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium join key for products to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "81",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+js4auzz35", "+uggjup17z", "/jmacfvzbq", "/nky7wavyh", "12lhc2qtbd", "1bpzc9ykyx", "1mebfzpwjh", "222zfuutd7", "2fldoea5xs", "3f1qz+5gwp", "3hfziqieun", "3l8idoxkye", "3pkoke/cta", "3qgp7bhrfp", "3wpnxowgij", "42klcdxlel", "4cgcfa71wr", "5hxm7s8vou", "6bc6f5wie1", "6ibpo1a/aq", "7p4qj8foum", "8b0vsowucn", "8w0/bxq90r", "9fzftii3+c", "ak+ufufnga", "ams3np/ex0", "anar1sqsw0", "atsg/pa8n6", "bd5dvzio0g", "bgqs45xora"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12752",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++r4xn4vr", "++/vuz4nk7", "++29ozw5dt", "++5ehyyrcf", "++7/iwjf/t", "++ayvxm7ih", "++bosno0na", "++dfr9kmbh", "++djtknrfu", "++fldwbhow", "++fo4zqvyc", "++ibbpjjey", "++ifp3an2l", "++nhjw/bue", "++pjn+dzie", "++stkfg9gg", "++yzvvrxl2", "+/1raf0piy", "+/3jzeyeoy", "+/ageqnzbv", "+/o8nkajlj", "+/qxtesqxb", "+/shwrgodz", "+/snirsvu+", "+/xc+ixlnz", "+/xohaogsm", "+0/sy6rkjq", "+026a5/taz", "+02nrvjcms", "+02om5az3b"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_refund_line_key",
+ "original_column_name": "sm_refund_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The unique refund line key created by SourceMedium that can be used to join refund line dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "14500",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++eobywj3", "++/zl5mzun", "++alqzu/p2", "++aoc8ze84", "++cevihsfj", "++cgrmol69", "++dtlhd9b2", "++gwngcj8l", "++hrayjz3l", "++i7i7wa+x", "++j9bw10td", "++jq6jdw4y", "++jtlcbkn3", "++mjx2wawq", "++n/4klinu", "++npckzhdl", "++olz+gz6o", "++q2dnkosr", "++r2arajkc", "++rrvsmrez", "++s/xabtbv", "++ssz/5y0k", "++sszrrnem", "++t33zazsy", "++tesgymqp", "++twjnjfvw", "++tx7nd7qb", "++umx8z8gb", "++umzh/sk6", "++uvttfi7+"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_product_variant_key",
+ "original_column_name": "sm_product_variant_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium join key for product variants to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "137",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+asq4bpdvr", "+ukxyxavka", "/xmwtvsoqw", "06kc4/ufen", "0zpmbpdgum", "18w1xxbypo", "1h3qx7jfvk", "26yxndo4gq", "2okmsovktk", "2vzixokyiv", "3niju+ygvm", "4rpfju6+zs", "4rxwjdadvm", "4rzqcmjxd3", "4vdmy9j+i1", "4vswk67lay", "5ngblrczv2", "5sqxpa02sk", "5uwmy4fyqn", "6hptcmtxhb", "7e0lmo78u+", "7vetvfrqzj", "8mv/l8hdlf", "93jqze/ljg", "9jwxq1svfe", "9puwu423wv", "agdjqbn5by", "aghrlwmw/d", "ahapva61gl", "ai2zy0j8wk"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "13.423373759647189",
+ "column_distinct_count": "10848",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++3qa2mtg3", "++8kka1bqd", "++cdt8yhcj", "++eegjygbb", "++ekdaxnyo", "++g+xmbf48", "++hqx86s3w", "++ignkdzkn", "++ipfvokmj", "++lywdhp4w", "++ms9md8dn", "++qldlixdc", "++qri41stb", "++suvvuueo", "++uxg8ajvd", "++wyedtojt", "++ztcokcpl", "+//8nzebym", "+/3+pn6qtf", "+/6gbycngj", "+/7w9z+k6s", "+/8+meydn1", "+/8hcqafcz", "+/9bsoghgd", "+/bhxk3/fs", "+/csuma0+w", "+/fv32opuo", "+/k383clp6", "+/m91gj1dr", "+/mmu5an5i"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "6356",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/oys3ymy", "++3edon5z1", "++cols7ohp", "++d1sqsweo", "++gquwnxus", "++nqxfi1z+", "++rk8521ux", "++svvn5x4c", "++z0wc2kvz", "+/drysdwsb", "+/mtik2kqf", "+/o48e27ln", "+/wzfykpop", "+0bs/5qyio", "+0col7mwjy", "+0fus95uy+", "+0l+ha7fht", "+0lv2bu8g7", "+0q0xkzbii", "+0qfveh65q", "+0rhdipmpk", "+0td+btrkf", "+0wd0l8go9", "+1/mp69ldq", "+1217ykkwd", "+12qiyctsr", "+14kf7ybyh", "+16p98s0w1", "+1cahk4ou4", "+1j3h0oku1"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_refund_key",
+ "original_column_name": "sm_refund_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The unique refund key created by SourceMedium that can be used to join refund dimensions to related tables. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "6504",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++1ren+h12", "++gcbhx2dm", "++jyt0rfe3", "++mnb90q5b", "++oup2vz52", "++p7ay9uo5", "++srkgp0du", "++wpxx/2fb", "+/1qjyt/ek", "+/3mkez/fc", "+/6hn43/oy", "+/jnjiiff9", "+/p9jtq9xw", "+/pofmaolq", "+/qku4ssky", "+/qvycdzik", "+/yvfpzlfh", "+/zno9adsi", "+0+pfrhs7y", "+0dsp+dz34", "+0ezmvj6pb", "+0jeaa1d8t", "+0nntobeai", "+0zkziobdy", "+1cb90mcxk", "+1g3e4wjjs", "+1im62roka", "+1qed6sjmi", "+1v+dxonem", "+21ckrsvdy"]
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_ticket_key",
+ "original_column_name": "sm_ticket_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Surrogate key for the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28805",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qqsjfc5", "++0io6svmy", "++2j6v+qse", "++2yauqafm", "++3/mzyngd", "++3/n2b0xi", "++4agyxktm", "++5uzcdils", "++5xqatwq5", "++6keq1iob", "++7gkfpdux", "++99x74mrs", "++ajzxahsg", "++an5snepc", "++azfwa4/c", "++b8eipk4r", "++beq4h+o5", "++bhtbrnmo", "++bjqhgln6", "++d8uhkjxz", "++daj6yreb", "++e3njjwua", "++eyj1g/o7", "++frhv56dj", "++geie3oer", "++gjjd1xr4", "++hfuzuvvh", "++hl7egtdv", "++jeypbrex", "++jr3o/1/e"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_entry_method",
+ "original_column_name": "ticket_entry_method",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "The method through which the ticket was initially created in Gorgias. Represents the \"via\" field in Gorgias that indicates how the first message of the ticket was received or sent from Gorgias (email, helpdesk, api, etc.). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["aircall", "api", "chat", "contact_form", "email", "facebook", "gorgias_chat", "helpdesk", "instagram", "offline_capture"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_excerpt",
+ "original_column_name": "ticket_excerpt",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Brief excerpt of the ticket content",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.020745453288154345",
+ "column_distinct_count": "23669",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++lred8hs", "++/abvlvol", "++091hg1rd", "++65gmxgik", "++9o+yuscz", "++b1kenjrx", "++bjgevmxb", "++bvm60w1j", "++c0p/ugpo", "++c6eh/doy", "++dlsy6eg8", "++e/qkaydb", "++eexbfwk+", "++h0ho6o6x", "++hionqox7", "++hmsz1zt4", "++ht6qxoz4", "++is3zc5ff", "++kitubl0x", "++laf96uzm", "++lye8akrq", "++manfrvfq", "++mfqx6iuq", "++mj6aprqp", "++mmr0pe1s", "++n/pdfyyd", "++n4gn8lul", "++obqbmzfu", "++pmtnl+mw", "++qsnvnyy6"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_status",
+ "original_column_name": "ticket_status",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Current status of the ticket -- open or closed",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["closed", "open"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_subject",
+ "original_column_name": "ticket_subject",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Subject line of the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.4719289659511991",
+ "column_distinct_count": "41",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Account access problem", "Account update", "Backorder status", "Billing question", "Business hours", "Cancellation request", "Color availability check", "Complaint resolution", "Damaged product", "Delivery delay concern", "Discount code issue", "Exchange inquiry", "General feedback", "Gift card question", "Loyalty points inquiry", "Media request", "Missing item report", "Mobile app problem", "Order modification", "Order status inquiry", "Partnership opportunity", "Password reset", "Payment issue", "Pre-order question", "Product information request", "Product quality concern", "Product recommendation", "Promo not applied", "Refund request", "Restock notification"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_tag_names_csv",
+ "original_column_name": "ticket_tag_names_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Comma-separated list of tag names associated with the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.11138056469773",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_assignee_team_name",
+ "original_column_name": "ticket_assignee_team_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Name of the team assigned to the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "80.197116902248254",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["CS - Sales", "CS - Support", "CS TEAM"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_assignee_email",
+ "original_column_name": "ticket_assignee_email",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Full email of the user assigned to the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.775098168676372",
+ "column_distinct_count": "42",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/dtho@example.com", "0fgvv@example.com", "2bxw9@example.com", "36s5k@example.com", "5qbe2@example.com", "7eqgj@example.com", "7wp0/@example.com", "9pnkq@example.com", "b5zjl@example.com", "b9bec@example.com", "bmqqx@example.com", "bwuj+@example.com", "fk93u@example.com", "ftw1y@example.com", "gmwoy@example.com", "gpfp/@example.com", "gr222@example.com", "h+e/e@example.com", "hyhjz@example.com", "ih48l@example.com", "irmtd@example.com", "itpbz@example.com", "jgs0z@example.com", "jn4c8@example.com", "kixkf@example.com", "kz4cg@example.com", "lswwz@example.com", "nigk5@example.com", "povff@example.com", "shbnv@example.com"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_customer_first_name",
+ "original_column_name": "ticket_customer_first_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "First name of the customer who created the ticket. Extracted from the customer support platform; may be NULL if not collected. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_assignee_id",
+ "original_column_name": "ticket_assignee_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Unique identifier for the agent assigned to the ticket. Links to the agent user profile in the customer support platform. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.58039433490697",
+ "column_distinct_count": "39",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+e8uozn0dw", "1pq4ustt6y", "2dc+vsspqx", "4o66sklgyd", "4oozvpnrop", "4qj1/auk3i", "5hfkqesm7k", "6is53wkyo8", "76arfi4hl7", "7nwvaqxcul", "8umz5dah5v", "a6suogdocy", "bzrq4tseuu", "cjrupxdnwm", "ctxo/refs1", "cwrknb/ptf", "d0w1xhwzu1", "d3lkiydkqf", "dommkt+gcm", "dtyg2hrgba", "ezk6v0x4u0", "i1lym9dp+l", "iocjfig8mo", "jrxyas0jpk", "jtpqhkgerc", "kpwpogla5f", "lujpzy53sr", "n7lvney/jv", "ornpgc0+wi", "pabpbuazas"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_customer_full_name",
+ "original_column_name": "ticket_customer_full_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Full name of the customer who created the ticket (concatenation of first and last name). Extracted from the customer support platform; may be NULL if not collected. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "21.684400862368733",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "The sales channel associated with the ticket.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["online_dtc"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system_customer_id",
+ "original_column_name": "source_system_customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Customer identifier from the customer support platform (e.g., Gorgias)",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Source system identifier",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["gorgias"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_communication_channel",
+ "original_column_name": "ticket_communication_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "The specific platform or channel used for ongoing communication with the customer. Represents the \"channel\" field in Gorgias that indicates where the conversation takes place (instagram-direct-message, email, etc.). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["aircall", "chat", "email", "facebook", "facebook-mention", "facebook-messenger", "facebook-recommendations", "help-center", "instagram-ad-comment", "instagram-comment", "instagram-direct-message", "phone", "sms"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_id",
+ "original_column_name": "ticket_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Original ticket identifier from the source system",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28519",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++rculwon", "++/hhshzet", "++/jawqkdq", "++0lcffszg", "++0vzu8z+c", "++1bei+t/u", "++2asd/3mh", "++2yerpn+u", "++3uyxjgdn", "++6dtqrcwu", "++8bpba/py", "++9kxupurb", "++9uls/0ff", "++adzgcc9v", "++ahxqjgim", "++awrb2n79", "++bq0kx6mt", "++bwx/iukm", "++col90vte", "++di0dzagn", "++ems0/xqm", "++esrqa1ig", "++eu9mdvqd", "++f3245v/w", "++fvqg6vqe", "++get6a98r", "++gr3vinia", "++hl08hjb6", "++hmrdqigr", "++htiijbmw"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Source of truth customer ID from ecommerce platforms (e.g., Shopify)",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "25.747670051467519",
+ "column_distinct_count": "16365",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++e7tqgmz", "++4o8z/i3h", "++6qkyjv/m", "++a/uxwxnq", "++amnpblqk", "++bioe+zfr", "++erqcos+d", "++f0m1uhec", "++fiaqm0zr", "++g3mfdqzi", "++iiiqh9ur", "++lpaljbla", "++olmc7/s7", "++ooqahvyy", "++oshqvqnq", "++p9waptot", "++qmmvslxh", "++r2rhl5on", "++skrlyaty", "++uton48kp", "++v+rdkgbt", "++vhsaxcny", "++yxsqjw9q", "+/1e56cwds", "+/7l2hvh3b", "+/9hx+aiaj", "+/bfoaysxn", "+/bu5txfob", "+/ci1zsfvr", "+/coytm3n6"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_assignee_profile_picture_url",
+ "original_column_name": "ticket_assignee_profile_picture_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "URL of the assignee\u0027s profile picture",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "61.476933871250658",
+ "column_distinct_count": "24",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["3iu8ep3ih3", "4rreielnjk", "6oiwdwlvbd", "72ruleo+/o", "75pwilkpnz", "94u0dwybow", "ahlatznlml", "aibizalha1", "bo/dhbhapf", "dcoq1p/asw", "dxlprsgrbt", "dy/ja1+lqe", "dypuubazs1", "f5pgrblj5+", "hglxfl7klf", "mn7wkrefmj", "mzxnbiimuy", "nsjhhmkq/g", "qxsvoyeig4", "rinmqnu2te", "sn5ay2x6np", "tmh4rtvybe", "w4y3zfdj6m", "wk1ubjfwuf", "xwm5seuzwy"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_customer_last_name",
+ "original_column_name": "ticket_customer_last_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Last name of the customer who created the ticket. Extracted from the customer support platform; may be NULL if not collected. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_assignee_full_name",
+ "original_column_name": "ticket_assignee_full_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Full name of the user assigned to the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.757807875770339",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "Elizabeth", "Emily", "James", "Jane", "Jessica", "John", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Sarah", "Thomas", "William"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_priority",
+ "original_column_name": "ticket_priority",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Priority level of the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["high", "normal"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_customer_email",
+ "original_column_name": "ticket_customer_email",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Email address of the customer who created the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "24.530471444998085",
+ "column_distinct_count": "16594",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/of@example.com", "++4ck@example.com", "++4tj@example.com", "++5ie@example.com", "++621@example.com", "++9nf@example.com", "++amw@example.com", "++arh@example.com", "++bb+@example.com", "++dlk@example.com", "++eco@example.com", "++egv@example.com", "++f2u@example.com", "++fdt@example.com", "++gys@example.com", "++i2r@example.com", "++j5/@example.com", "++leg@example.com", "++n5d@example.com", "++nwr@example.com", "++rk+@example.com", "++s69@example.com", "++vie@example.com", "++vzt@example.com", "++wux@example.com", "++x8l@example.com", "++yfv@example.com", "++zkz@example.com", "++zzk@example.com", "+//fg@example.com"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_custom_field_csv",
+ "original_column_name": "ticket_custom_field_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Comma-separated list of custom field ID-value pairs for the ticket",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "72.421266035163754",
+ "column_distinct_count": "1842",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++5kni4ych", "++a6y6bhse", "++dh/cgscu", "++dy6rjgkn", "++ukmr754f", "++xvh5j9ee", "+/1pk5dihi", "+/jywgkxtv", "+0cfbpdqhu", "+0pds8cy4v", "+18f//blev", "+2cyft8jno", "+2dfcmxlhu", "+2pddabims", "+2x6oyx/lw", "+3jpcbqwtv", "+3k7lyi0t4", "+3xhdrs2+3", "+4kcyhzjbz", "+4xrfewtrk", "+589elidzl", "+5l9kcyilt", "+68/9l+etj", "+6gxh8xwmp", "+6l463eit/", "+83ggfotqt", "+8er3bjfxz", "+8ld9rd2op", "+8ls2wuhzu", "+a1hgit831"]
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_external_id",
+ "original_column_name": "ticket_external_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "External system identifier for the ticket",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_last_name",
+ "original_column_name": "customer_last_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Customer\u0027s last name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.98546402456536",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscriber_id",
+ "original_column_name": "subscriber_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Unique subscription platform identifier when subscription integration configured (e.g., ReCharge, Skio, Loop, Retextion). NULL for non-subscribers; reflects current/most relevant subscription linkage at snapshot time. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_street_address",
+ "original_column_name": "customer_street_address",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The customer\u0027s street address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.998890528441308",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["zjqmcsp4/+"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_first_name",
+ "original_column_name": "customer_first_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Customer\u0027s first name as provided during account creation or checkout. May be null for guest checkouts or incomplete registrations.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.639234217325054",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "last_order_id",
+ "original_column_name": "last_order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The ID of the customer\u0027s last order. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "62.336835402737975",
+ "column_distinct_count": "1184",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_address_country",
+ "original_column_name": "customer_address_country",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Country from customer\u0027s primary address (platform-reported names). Coverage varies by source_system; Amazon often has NULL/obfuscated data. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.469503074621912",
+ "column_distinct_count": "16",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["American Samoa", "Australia", "Austria", "Bahrain", "Belgium", "Brazil", "Bulgaria", "Canada", "Chile", "Colombia", "Costa Rica", "Croatia", "Cyprus", "Czech Republic", "Denmark", "Ecuador", "Finland", "Guam", "Hungary", "Iceland", "Ireland", "Japan", "Korea, Republic of", "Kuwait", "Latvia", "Lithuania", "Luxembourg", "Malta", "Mexico", "Morocco"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "first_order_id",
+ "original_column_name": "first_order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The ID of the customer\u0027s first order. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "64.306038570976924",
+ "column_distinct_count": "1130",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_source_system",
+ "original_column_name": "subscription_source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The e-commerce source_system used to facilitate a customer\u0027s subscription. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_address_zip_code",
+ "original_column_name": "customer_address_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The postal code of the customer\u0027s location.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.506017141080861",
+ "column_distinct_count": "3150",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["0000", "00000", "00141", "00510", "00602", "00610", "00646", "00662", "00674", "00678", "00680", "00681", "00683", "00690", "00693", "00698", "00703", "00716", "00717", "00719", "00723", "00727", "00729", "00730", "00738", "00745", "00754", "00765", "00771", "00777"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "90365",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++6zhuhay", "+++a+ijdbn", "+++eczts6a", "+++gy97hhl", "++/2owaa+a", "++/ig1wufg", "++/j9+wxy1", "++/oys3ymy", "++/w4t2wpo", "++0ys8prkj", "++14m2sxd2", "++1k648y7b", "++1ke1ua/w", "++1mzb2abb", "++1r/upzxk", "++1xydt8nd", "++2fhrcyos", "++2fl2evwe", "++2hpretae", "++2j7b1tb8", "++2msoapoy", "++2oh6icyp", "++2ukk+eyo", "++3edon5z1", "++3kivwhbl", "++3krn85mm", "++3zzz8vt5", "++4bwwkjkc", "++4cksd2o9", "++4datdb1c"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_address_city",
+ "original_column_name": "customer_address_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "City from customer\u0027s primary address (free-form). Coverage varies by source_system; Amazon often has NULL/obfuscated data. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.440151298572786",
+ "column_distinct_count": "2011",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["01/27", "4/3 Cr", "Abbeville", "Abbotsford", "Aberdeen", "Abilene", "Abingdon", "Abington", "Abiquiu", "Abita Springs", "Absarokee", "Abu Dhabi", "Acampo", "Accokeek", "Accord", "Acton", "Acton Vale", "Acworth", "Ada", "Adair", "Adairsville", "Adams", "Adamstown", "Addieville", "Addison", "Adel", "Adelanto", "Adelphi", "Adrian", "Advance"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscriber_status",
+ "original_column_name": "subscriber_status",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The status of the subscriber. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_email_hashed",
+ "original_column_name": "customer_email_hashed",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "SHA-256 hash of customer email address. Used for privacy-safe customer matching and analytics across systems without exposing PII.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.1903842547135466",
+ "column_distinct_count": "89895",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++a2He8KWX0t+1TWZEc+2zidcf9LYT47kXO7FgMEIk\u003d", "+++f3JFVxLc0ECZDdDOHWNpkNgNFAWZ/5BXy3R1V2e8\u003d", "+++y082xp8psaCCxobeDLoeoBI9RHaLijBSYI1gBBnc\u003d", "++/euVoIcwG3E/1QoWYlLXj05U0pS973N/Z54bvuKsI\u003d", "++/ofCQBxnxZ+Xs5Dwr/ZnHVGpPP1CGFv8iyLWbhpd4\u003d", "++0/RWguRnoX+/NXfyKPLmx7t18PpU1VtLDVxFq/TZA\u003d", "++095Y26PZ5/cELKdEvwlqKqf8MxJp9AI5DD9TOFN9w\u003d", "++0CAJXn4nyuCvXquMaAcqCtnQkX5OHFE0ri3PbEmcs\u003d", "++113Avb8EqnawoWRClwFaVj9FSKmwNz84yssORIYL0\u003d", "++17RspQ942mQdNvMNtpfVqoxyuUqn0dAWBx0P/I/kY\u003d", "++1ITsrj41aEIkC/4REmtkJM/QuikIw2kGVfXqL8EVY\u003d", "++1WKQBK3urm/S4RbY65OErwDApRz1X7NjMrr7nUG8I\u003d", "++1h2Vpefyk+F2g9F9tN0zPNYb5BQIJwkJcpDL8WVbY\u003d", "++24vdZQUXGmIkbcxf1PsaTSESMQPnFHJxXegKwsA08\u003d", "++356k1I9MDkoC99R+TCig5VdGUAqTFa6XmDltBvpCw\u003d", "++3mNMqtt1ZDHMVeeB/Sf2+3U2hqyth07G/k2BxfOPQ\u003d", "++3mj59hala6pmtXtUQdV1QR0CfY70D3d85ZbwvnDUE\u003d", "++3nRHomg2DZlUxWbwnfgVw31rACXaa1u2mmDkAuieQ\u003d", "++3yNo1r8qDQuL/4aqKS1zFlPt6X176vwq0Vy4lb4FM\u003d", "++4C2mLz7q1xc+BalftlxpRHS+uPXoT93+K47izNJqc\u003d", "++59dWW44BBeKz0L94qKthO3/u8pkFyg8+jhEloyvM4\u003d", "++5f3Qau4V0eiH41mdJ49ucGBqlH8KAoFRCZO5FH4k8\u003d", "++5ik42quMqXB3dy5WC3oxtoAN3d9wvY4DHY+gE53n4\u003d", "++5qtgHNvEDPQ7DxTL2t7ucztViusI2zX0LTVuC/wHM\u003d", "++5xTnzYl4jYIb2nnjfkDpG2HrBJNoEjJSKJUK3EA5c\u003d", "++621n2F5KjUoTpQUhqpe9tyKZEmQs2A8kgRZ04WkJs\u003d", "++6JVsxKB43J7e2O9Sg0T855QepgVRBCI6q3kOAk2uI\u003d", "++6UrGGc6tAxh7aMI/aAiHfe1AX31lCCAP/RNw5lv4k\u003d", "++6di/jv1G7DaMJ8BnJsjBgpYwRYucFume+NEXX5KVg\u003d", "++6p0tE6MHhWSPIrEszxWh7V1L2JW3rXgLhv6n88KjM\u003d"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_phone_number",
+ "original_column_name": "customer_phone_number",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Customer\u0027s phone number in platform-provided format (varies by source_system). May be NULL if not collected; formatting and country codes not standardized. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "70.333760381692883",
+ "column_distinct_count": "26833",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++5kdpbs", "+++71zw3ej", "+++9mf+p1x", "+++h/4e4pv", "+++ntpw4wy", "+++udwmxfl", "+++ut4mpux", "++1i74h/za", "++1zborgmg", "++2enui81i", "++2iilsf7t", "++2nn+8zbd", "++4xm/4ccf", "++5yptogrv", "++6a5bndo/", "++6eoggewp", "++6l2nsveo", "++a/vrf8pc", "++bbs0lbj8", "++bun5xfze", "++bxa+h4ju", "++cnohc/sv", "++co5fqv/u", "++cpj2ashi", "++dkluggzg", "++dsa5vrpg", "++el4dhgz/", "++enwrv0f6", "++eoqnkfq9", "++fgjlpvvl"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_address_province",
+ "original_column_name": "customer_address_province",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The province, state, or district code of the customer\u0027s location.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "95.493953282898",
+ "column_distinct_count": "133",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+3cukctf5y", "+fit3krm93", "+q9jjptidl", "/8e8+6s/j9", "/forwn2/lx", "/ihcxkhzfq", "/thycvbvqp", "02tlyfrck7", "07mixcx0b4", "0d0dljgjwp", "0lremkttam", "0qskamw9uo", "0qzpychlve", "0sxnzp2eam", "0v38kkvd7n", "0yoptkg8pe", "11eleiesy5", "16jznege60", "1jqfockdvw", "1qibvicd1j", "1siblilyqx", "1tnnl8oaei", "22vwk67dub", "269f6gw0n5", "27fwejhwzr", "2fuxjfjhmj", "2gibynedzt", "2ttfbmonar", "35s9asqrhh", "3hsbu7b9qp"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The ID of the customer who placed the order.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "90479",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++oygjqva", "+++vc5jh+8", "+++z2m4hz4", "++//ladtyl", "++/4eczdec", "++/bfhxibh", "++0/01cxij", "++0qrmjzag", "++0ut81wbd", "++0wixgstj", "++0xszpjx+", "++11lgfnmx", "++18jy5m9z", "++1itiwxoy", "++2p3gidnp", "++2xzj6doa", "++30yfw4bu", "++3f7rb07a", "++3jfk8okg", "++3ofgbo9h", "++3tshcdaw", "++3yuf2kb+", "++4ajmgssa", "++4o8z/i3h", "++4vsytq06", "++4x2pmnrg", "++5+cdjg7k", "++5fwch7kg", "++5kqolf8p", "++5sp0ujz2"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_email",
+ "original_column_name": "customer_email",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Customer email address (PII); see customer_email_hashed for privacy‑safe matching.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "1.1977492843118975",
+ "column_distinct_count": "90025",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++a2@example.com", "+++f3@example.com", "+++y0@example.com", "++/eu@example.com", "++/of@example.com", "++0/r@example.com", "++095@example.com", "++0ca@example.com", "++113@example.com", "++17r@example.com", "++1h2@example.com", "++1it@example.com", "++1wk@example.com", "++24v@example.com", "++356@example.com", "++3mj@example.com", "++3mn@example.com", "++3nr@example.com", "++3yn@example.com", "++4c2@example.com", "++59d@example.com", "++5f3@example.com", "++5ik@example.com", "++5qt@example.com", "++5xt@example.com", "++621@example.com", "++6di@example.com", "++6jv@example.com", "++6p0@example.com", "++6ur@example.com"]
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_csv",
+ "original_column_name": "customer_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "Comma-separated list of all tags associated with a customer. Use for simple filtering; beware that individual tag values may contain commas.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "86.577336641852781",
+ "column_distinct_count": "29",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_page_path",
+ "original_column_name": "event_page_path",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "The URL path of the page where the event occurred (e.g., \u0027/products/item-name\u0027). Normalized to remove special characters; use for page grouping in funnel analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "48321",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/", "/-finalday", "//", "//a/account/quick-action/reactivate/933dfdb2-f58e-4249-a89d-3a67341fb870", "//pages//warranty", "//products//device-cleaning-solution", "//www", "/112794", "/1127948", "/11279482/", "/11279482/checkouts/0466034c305e67c0713000a423b50664", "/11279482/checkouts/1ae60c5f593ced8a7267df3806055c7b", "/11279482/checkouts/1ee1fdd33be38b43aedd50b3e38e32fc", "/11279482/checkouts/1f617c3d259dde4d9d1e6f85ad68b2f5", "/11279482/checkouts/236f5844fb3648d8561e32e430693f9a", "/11279482/checkouts/2ddc154a98e14d30728a5625c5e350dc", "/11279482/checkouts/2f602a83394337b0a3f5151080454912", "/11279482/checkouts/308f556dfbe33dfa0059191d6a39ee0b", "/11279482/checkouts/40c1a26266d73d485f04ede090cb401b", "/11279482/checkouts/4182b330836ed9758c7ddb3bf69130e0", "/11279482/checkouts/4f2934b3325b4d1e78fa724da9a03dba", "/11279482/checkouts/4ff538dee9d0ac10abb08f6b8ca6248d", "/11279482/checkouts/511e7cb6880e42edc6eae799c70c78f0", "/11279482/checkouts/58facace7acafada5c5cbe7c80d83188", "/11279482/checkouts/5e49128d6d55cafe4484b3f5cac745bd", "/11279482/checkouts/72a9ebd6377c905de07c4916cef19c05", "/11279482/checkouts/7538d74248dbf34b1cfe4857e3b64a7d", "/11279482/checkouts/7580e025cf26cf33ea3dbd6091b73314", "/11279482/checkouts/8258cb26cf4a181ac2437e1410ed07da", "/11279482/checkouts/8c526c657d828402d19abaae44137efb"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer_medium",
+ "original_column_name": "event_referrer_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Marketing medium extracted from the referrer URL (e.g., \u0027organic\u0027, \u0027cpc\u0027, \u0027social\u0027). Used for medium-level attribution when UTM parameters are not available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_label",
+ "original_column_name": "event_label",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Event label from analytics platforms providing additional context about the event. Used for detailed event segmentation and custom tracking analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_session_id",
+ "original_column_name": "event_session_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Platform-specific session identifier for the user\u0027s browsing session. May differ from event_user_session_id depending on tracking platform; used for session-level analysis.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_phone",
+ "original_column_name": "event_user_phone",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Phone number of the user who triggered the event, when available from tracking platform. Format varies by platform; used for user identification in phone-based campaigns. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "89.366344857884556",
+ "column_distinct_count": "51678",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++0eekeqb", "+++ntpw4wy", "++/rxqbfvl", "++1zborgmg", "++2iilsf7t", "++50py1q24", "++6l2nsveo", "++8f3kjgrf", "++ddiwrpgr", "++dkluggzg", "++dkogr8sm", "++dqu6wfri", "++dsa5vrpg", "++flw2fofj", "++gxablec4", "++iip1dcdm", "++iz9c645x", "++jbjwh1f/", "++jrmsdhim", "++jz2sm0gz", "++koqjj2ko", "++kvjtekr3", "++lmnbm2jc", "++lvfffqbg", "++lzgp/smk", "++oqwvicmw", "++pjivzbv9", "++qqiqwb8k", "++qvjuqebs", "++rtaslcbc"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_screen_resolution",
+ "original_column_name": "event_screen_resolution",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Screen resolution of the device where the event occurred (e.g., \u00271920x1080\u0027). Used for device-specific funnel optimization and responsive design analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_source",
+ "original_column_name": "event_utm_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM source associated with the event (if available). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_checkout_token",
+ "original_column_name": "event_checkout_token",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Unique token for the checkout session associated with the event. Used to track checkout abandonment and recovery flows across multiple events. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.18883337495059",
+ "column_distinct_count": "36204",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++ceatqu5", "++0cfemcmi", "++1lj4yek2", "++4aimypg5", "++4bk512jh", "++5wup+1kc", "++7k7vimfp", "++7sr27+bv", "++7wvckxhz", "++aydyjlm7", "++b2dnmaaf", "++bbijigih", "++cvuhtaed", "++cvvjgios", "++cwbaw+hi", "++dfkxzblw", "++eeushzvt", "++ekunnr6y", "++fabc8k5l", "++g5cxjbwz", "++hj4y2mny", "++igaelrs+", "++iwstgj5k", "++iwtv16re", "++jpt5o6a8", "++jykm0zel", "++lerinfwm", "++lzoklzj9", "++m+jnpnzi", "++mn9qn0fr"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_page_url_with_params",
+ "original_column_name": "event_page_url_with_params",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Page URL with all original query parameters.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "548470",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(select(0)from(select(sleep(15)))v)/*\u0027+(select(0)from(select(sleep(15)))v)+\u0027\"+(select(0)from(select(sleep(15)))v)+\"*/uutrgqiy0n", "@@04vzrxny7brpmtl", "@@0n66dclwpik7/mc", "@@1dlhciowppl6rse", "@@52nic9/bf4s2tt9", "@@5l20gycrsr+irto", "@@5xixmger70b/uus", "@@6ut36yovwb1oqqj", "@@7lx7nallzclmrxx", "@@9npihvogvixt4yg", "@@ag6s2wzqu4gj141", "@@asmwtoaxqkie0bs", "@@bkjseytqom2pqvm", "@@byprwjk5mw4natm", "@@cfdwzxeiqlp+tvw", "@@chhg9norrtviwli", "@@cl5oauir2dqspmk", "@@cvn1t5dnsltaz8b", "@@dulrycchjyz3eyk", "@@e8anyrln4swsp0i", "@@eoy4wkgz1n5lyn9", "@@fotesqzlprrodmj", "@@fp0vb/17u68cscz", "@@gf9ovcwiqnldkwj", "@@gnkhtjdm0+jyx8r", "@@gsmpfqjjcu4rxmo", "@@gyl4r3e5zodhe6t", "@@gytz1upkmhy/0s9", "@@hpus9g5vz419zof", "@@hrmfqkzmikwqhgh"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_province_code",
+ "original_column_name": "event_user_province_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "State/province code of the user who triggered the event (e.g., \u0027CA\u0027, \u0027NY\u0027). Used for regional segmentation and state-level funnel analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "87.335367935150884",
+ "column_distinct_count": "296",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+/nev9q9dv", "+7e4/1kn8+", "+9dnywskh4", "+fvd9o9trs", "+jt5e/s8ty", "+mddhqga4g", "+oxroucqb/", "+qhb86tjnx", "/3siwvoffh", "/57j98t66f", "/bqgtzy+jc", "/cm9un0idl", "/ihcxkhzfq", "/thycvbvqp", "07mixcx0b4", "0sajv1aqzc", "0w1km/y1fy", "0yoptkg8pe", "1gl3wtpupu", "1lpztiriv4", "1olwzqz6x3", "1tnnl8oaei", "218acfpewg", "26ymudnipc", "2ffbks1xq7", "2gibynedzt", "2ms3hh9vii", "2nbo1tjehf", "2teutu1zqr", "2w0u9vzo6z"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_gclid",
+ "original_column_name": "event_gclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Google Click Identifier (GCLID) from the event, used for Google Ads attribution. Links events to specific Google Ads clicks for conversion tracking. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "96.617561867389384",
+ "column_distinct_count": "35165",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/+hz/zwt", "++2ny2day+", "++2ujiulyd", "++4hiueeqd", "++4qhxtg7f", "++7gbhk21q", "++9+u5586x", "++99mdlx7i", "++agun8wtp", "++ajrhcfmu", "++c7xsuxn6", "++cdbyzxag", "++cofvaivr", "++d8dpazwg", "++ep2qbgfq", "++eqxedrex", "++fb8ld5ib", "++fgsch/5r", "++fhnyqhuh", "++fynx7h6o", "++gjk/w6lm", "++hc3erwem", "++ismcnh6s", "++jggyjpb/", "++k3phlwyy", "++kzw3bwbh", "++lcodjydp", "++le2p+o6h", "++lfhbw1p4", "++lhnoqby7"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "user_user_agent",
+ "original_column_name": "user_user_agent",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Browser user agent string from the event, identifying browser and device type. Used for browser compatibility analysis and device segmentation. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "_source_system_relation",
+ "original_column_name": "_source_system_relation",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Internal dbt field identifying which source model this event originated from (e.g., \u0027int_elevar__funnel_event_history\u0027, \u0027stg_ga4__unified_events\u0027). Used for debugging and understanding data lineage across the union of tracking platforms. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system_event_name",
+ "original_column_name": "source_system_event_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Original event name from the source platform. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["dl_add_payment_info", "dl_add_shipping_info", "dl_add_to_cart", "dl_begin_checkout", "dl_login", "dl_purchase", "dl_remove_from_cart", "dl_select_item", "dl_sign_up", "dl_subscribe", "dl_user_data", "dl_view_cart", "dl_view_item", "dl_view_item_list", "dl_view_search_results"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_event_key",
+ "original_column_name": "sm_event_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Internal SM event ID that\u0027s unique for each row.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1379528",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++/h2qdiz", "+++05odjfw", "+++4ierjdc", "+++5scugqj", "+++6g+zkt1", "+++7j9vtaq", "+++7qqaul0", "+++80agc1i", "+++90kli/v", "+++9cvdpdt", "+++9zaookx", "+++agja5+h", "+++bxnm6yy", "+++dcpdkmi", "+++dqh4cmk", "+++elqmt8m", "+++favv/eb", "+++fwuij69", "+++gtgmj4j", "+++h4sbyzf", "+++hd7vhrt", "+++he/vx2w", "+++i06xnrp", "+++iou+8qk", "+++ipreogg", "+++j2obi49", "+++jmpejt8", "+++jqyn+eg", "+++ju6/mnq", "+++lj9fv5a"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_id",
+ "original_column_name": "event_utm_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM ID parameter from the event URL, used for campaign tracking across Google and other platforms. Links events to specific marketing campaign IDs for attribution analysis. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "88.513097993040049",
+ "column_distinct_count": "2684",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+26ojmerhn", "+2c6mldiwp", "+3rnniqmyj", "+3zi2jfxpj", "+49hvawplw", "+4obh1dn7f", "+4rvoomvul", "+7mjdvdavx", "+8xfpgrzsl", "+albt6ppsb", "+an+n3egvi", "+b/qfqt8vf", "+bckoxwmwy", "+duhqx2hvh", "+eeclfiv7a", "+exg3wult7", "+fe0lliv5c", "+fxs8nch1q", "+g5wqwv9fo", "+hxw6awduy", "+jxq1zeefq", "+ksbk2ozmk", "+lgq2pv8ft", "+lvu2iowy8", "+m1dertfpi", "+mebcyzpr1", "+mz9dh9n6m", "+n4tlrhktj", "+nnew2swua", "+nzidqjvbl"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_campaign",
+ "original_column_name": "event_utm_campaign",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM campaign associated with the event (if available). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "25.666348612092388",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["acquisition_campaign", "anniversary_sale", "back_to_school", "brand_awareness", "bundle_promotion", "clearance_event", "customer_appreciation", "email_blast", "end_of_season", "fall_promo", "flash_sale", "holiday_campaign", "limited_time_offer", "loyalty_program", "mega_sale", "member_exclusive", "new_arrivals", "newsletter_promotion", "product_launch", "referral_campaign", "remarketing_push", "retargeting_ads", "retention_initiative", "seasonal_promo", "social_media_promo", "spring_launch", "summer_sale_2024", "weekend_special", "win_back", "winter_deals"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_action",
+ "original_column_name": "event_action",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Event action from analytics platforms (e.g., Google Analytics event action like \u0027click\u0027, \u0027submit\u0027). Used for understanding specific user interactions within event categories. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "user_zip",
+ "original_column_name": "user_zip",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "ZIP/postal code from user IP geolocation or profile data. Alternative to event_user_zip_code; used for geographic segmentation. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_page_url",
+ "original_column_name": "event_page_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Page URL with the query parameters removed.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "49032",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(select(0)from(select(sleep(15)))v)/*\u0027+(select(0)from(select(sleep(15)))v)+\u0027\"+(select(0)from(select(sleep(15)))v)+\"*/uutrgqiy0n", "@@04vzrxny7brpmtl", "@@0n66dclwpik7/mc", "@@1dlhciowppl6rse", "@@52nic9/bf4s2tt9", "@@5l20gycrsr+irto", "@@5xixmger70b/uus", "@@6ut36yovwb1oqqj", "@@7lx7nallzclmrxx", "@@9npihvogvixt4yg", "@@ag6s2wzqu4gj141", "@@asmwtoaxqkie0bs", "@@bkjseytqom2pqvm", "@@byprwjk5mw4natm", "@@cfdwzxeiqlp+tvw", "@@chhg9norrtviwli", "@@cl5oauir2dqspmk", "@@cvn1t5dnsltaz8b", "@@dulrycchjyz3eyk", "@@e8anyrln4swsp0i", "@@eoy4wkgz1n5lyn9", "@@fotesqzlprrodmj", "@@fp0vb/17u68cscz", "@@gf9ovcwiqnldkwj", "@@gnkhtjdm0+jyx8r", "@@gsmpfqjjcu4rxmo", "@@gyl4r3e5zodhe6t", "@@gytz1upkmhy/0s9", "@@hpus9g5vz419zof", "@@hrmfqkzmikwqhgh"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_zip_code",
+ "original_column_name": "event_user_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "ZIP/postal code of the user who triggered the event. Used for granular geographic analysis and local market segmentation. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "90.620059556332251",
+ "column_distinct_count": "18359",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["\t46012", "\t84624", " \t3190526", " 61701", " 9 --", "#1380", "000", "0000", "00000", "000105", "00042", "00047", "00100", "00136", "00143", "00146", "00154", "00155", "00158", "00165", "00167", "00175", "00184", "00195", "00202", "00220", "00330", "0037", "00600", "00601"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_term",
+ "original_column_name": "event_utm_term",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM term associated with the event (if available). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "62.821760328158746",
+ "column_distinct_count": "8369",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++rndyamyy", "++tgpf9vie", "++u2agbo+y", "+/biamosfy", "+/ktukdctv", "+/wyacqtzn", "+0anec+pds", "+0fc3wumak", "+0zylcd7wy", "+27izfzlnh", "+2mwhz0zcx", "+2tgwk88gf", "+2vjnhcp7m", "+36kjy0s11", "+3et4dkquh", "+3g7zczcg/", "+3q5oeuvmv", "+3s29dl4cf", "+584vvezrh", "+5b1mwkey1", "+5qfpbi/ke", "+5vnwtgox7", "+6a3zp6gck", "+6udxvgd6/", "+76c2uvrb9", "+7jt/x2zj+", "+7ppb+sp+h", "+7sry7t+ha", "+7ut9s+3sp", "+8dclzwkq2"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_order_id",
+ "original_column_name": "event_order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Associated order ID when the event relates to an order (e.g., purchase). ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.546686619831078",
+ "column_distinct_count": "6203",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++8yfuxzom", "++aaiqewlf", "++fbhty6ci", "++ilqda3tf", "++kizvtm95", "++pv/9yqmr", "++qgldwh/g", "++sy3kpa9n", "++tpse6hjn", "++uhny/rqt", "++vlh6lcs9", "++wpcmsfa4", "++y4y7xz2i", "++zp09cjnv", "++zsksiyv4", "+/2lkjuj64", "+/3p2dqc3m", "+/47zmbv5l", "+/800mmve8", "+/8byhwgek", "+/8jqfcna5", "+/8okbafsk", "+/9zvwkfk5", "+/b19wffrq", "+/b7kccxgb", "+/db419/k9", "+/dong665b", "+/jj1z8vca", "+/kovwhwxa", "+/mka2hzpj"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_fbclid",
+ "original_column_name": "event_fbclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Facebook Click Identifier (FBCLID) from the event, used for Meta/Facebook ad attribution. Links events to specific Facebook/Instagram ad clicks for conversion tracking. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "99.974250425522627",
+ "column_distinct_count": "337",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++70tkc9kx", "++gyht5ido", "++nd6fwck1", "+/fcmder6z", "+/inurskst", "+/xvolofhd", "+2mxlcuqvv", "+496xh/ra2", "+4qv5d1shz", "+660ww0xkn", "+81rodk6d3", "+9kp2xhr5x", "+bdjz9yoey", "+c3va3pyzb", "+ecvnpvbjw", "+efxcbkyyp", "+esdv0ocqr", "+gakqjptu9", "+gftdttuhc", "+ii8gqkw9j", "+iokhjixoq", "+jcomv9me4", "+jxkxhs9zm", "+kub48bame", "+l9xxvby03", "+lvga+tyl0", "+msaaqt6re", "+nezm0npb5", "+ngt0/frz8", "+nuhn4dkwi"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_landing_page_ad_id",
+ "original_column_name": "event_landing_page_ad_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Facebook/Meta ad ID extracted from the landing page URL parameters (fbadid or ad_id). Used to attribute events to specific Meta advertising campaigns. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_id",
+ "original_column_name": "event_user_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Platform-reported user identifier (distinct from customer ID) associated with the event. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.10410971270815572",
+ "column_distinct_count": "901738",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++/2dincp", "+++/s+nkb4", "+++4wwpe5d", "+++6azgnv1", "+++6vlxycc", "+++7rymdfg", "+++9s4il/p", "+++apem64y", "+++ayzr60q", "+++d/eo9q7", "+++dj99lhi", "+++dzbr1/d", "+++exm+gqg", "+++hwzvf+j", "+++jyoogss", "+++kb4301k", "+++rddaqjo", "+++u/zzlxd", "+++wwnouhx", "+++xroec7z", "+++yrlfks1", "+++yxrlj9o", "+++zp5g4et", "++/18gufci", "++/2ohzcky", "++/3cwfuln", "++/4dtad1s", "++/59bgsnt", "++/8bp5gla", "++/9k3yzhy"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_experiment_variant",
+ "original_column_name": "event_experiment_variant",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Variant identifier for the A/B test or experiment (e.g., \u0027control\u0027, \u0027variant_a\u0027). Used to compare funnel performance across experiment variants. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "user_ip",
+ "original_column_name": "user_ip",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "IP address of the user who triggered the event. Used for geolocation analysis and fraud detection; may be anonymized based on privacy settings. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_customer_id",
+ "original_column_name": "event_customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Platform-reported customer identifier associated with the event. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.13326880766617",
+ "column_distinct_count": "22443",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++oygjqva", "++3ofgbo9h", "++6c5yjnfi", "++8+hlufw1", "++a/uxwxnq", "++bqtlg4fd", "++dtqxslva", "++iiiqh9ur", "++lpaljbla", "++nk/wgfb3", "++ohr2bdgz", "++oshqvqnq", "++ostmgvzu", "++p9waptot", "++sjs1mdw1", "++ua6vfh8m", "++udyhtamk", "++ulf2f0ts", "++uton48kp", "++w3crosvv", "++yxsqjw9q", "+/+8uskl6i", "+/0bvmxfqy", "+/1e56cwds", "+/7l2hvh3b", "+/83qwp7kr", "+/9v0o3ygd", "+/a0+dehxs", "+/bfoaysxn", "+/d7ztlawk"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_medium",
+ "original_column_name": "event_utm_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM medium associated with the event (if available). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)", "cpc", "email", "paid_social", "sms"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_session_id",
+ "original_column_name": "event_user_session_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Session identifier for the user\u0027s browsing session when the event occurred. Used to group events into sessions for session-level funnel analysis and pathing. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.092065203140705348",
+ "column_distinct_count": "1057233",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++2hnbic+", "+++4jedbgr", "+++5zuyhlz", "+++afp6exz", "+++befu7h8", "+++e5/ob8/", "+++fuckhec", "+++jawzoha", "+++jo/65dq", "+++lmbpp5k", "+++mzrpw29", "+++nj/zory", "+++nqlu4xc", "+++plg0hwh", "+++qr/yfjl", "+++shwdkl2", "+++syt5nvf", "+++vzys5qr", "++/0wrfqtq", "++/9i+mi28", "++/bla0vrn", "++/cikkdy1", "++/hswa/55", "++/i6jl6gi", "++/kedj9oa", "++/kj52hl3", "++/kkr0peh", "++/mi+282n", "++/qf4zvin", "++/t/gbo9/"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_checkout_id",
+ "original_column_name": "event_checkout_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Checkout identifier associated with the event when the event occurs during a checkout process. Used to link funnel events to specific checkout sessions for abandoned cart analysis. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "97.510302385489581",
+ "column_distinct_count": "31932",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++ta+xqq7", "++1cq4/ieq", "++1tjqusww", "++3jkosrgo", "++3yq16juh", "++4w312icp", "++4xnsmxkb", "++4xp+qetm", "++5+mqlo0y", "++7mhn0qbt", "++8law+vw5", "++9s4y44e5", "++afhanqxg", "++dl6ftvut", "++dr2lvgd+", "++e2g9nuz8", "++eb8wczcc", "++ewpodmse", "++gcfug8fq", "++gpi8upaj", "++hnnzr5xc", "++hplnhy1k", "++hrop0gwx", "++isitjmnj", "++izoq6yaq", "++kifipawd", "++kzkelzby", "++lheowciz", "++mgzfg1n3", "++mltqih1w"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_category",
+ "original_column_name": "event_category",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Event category from analytics platforms (e.g., Google Analytics event category). Used for grouping events by type in custom event tracking implementations. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_id",
+ "original_column_name": "event_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Platform-specific identifier of the event instance. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1366492",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++1wgsh8", "+++005wnov", "+++13fvwmv", "+++2dh716i", "+++32rv7s8", "+++35v/yuy", "+++3k4u6c5", "+++68mqbhj", "+++6nd0aod", "+++a9wjfo3", "+++azsce7l", "+++bgd9gam", "+++cx2qrhp", "+++d+bwlyi", "+++d8ri76z", "+++dl71hli", "+++dvco8hm", "+++e87+k4b", "+++efoxs45", "+++exw+tf1", "+++gkeee3o", "+++gq+kvqd", "+++gvhtiel", "+++hntudoa", "+++hss13uf", "+++iw2qf2q", "+++kkkeydw", "+++kqlo9ax", "+++l4+ifro", "+++lficdw9"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_utm_content",
+ "original_column_name": "event_utm_content",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTM content associated with the event (if available). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "40.70418964869188",
+ "column_distinct_count": "6917",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++dktxnmpj", "++vuyjnqh2", "+/9iesbxsk", "+/hw2fnkr7", "+/rrm+r6uw", "+0ibrpd/d9", "+0ngvpf3/q", "+1n5s0mntm", "+1poviumbf", "+2mnsa/sap", "+2moz4tvn2", "+3itffxq9c", "+3os2ofaa8", "+3plxlabf9", "+4/h5g1k0f", "+47euyimiu", "+4bkiprgvp", "+4rk9hmwjr", "+4rmqmwnpg", "+63bxygrdc", "+6bgigwtoa", "+6daxcwu/b", "+6hz/ijdjm", "+7jvdrkz2d", "+7wgdqy7h9", "+8k241u5hb", "+8qo0wyhuz", "+8ux+a2b4m", "+9ybjllw42", "+ar+6rxvnd"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_email",
+ "original_column_name": "event_user_email",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Email address of the user who triggered the event, when available from tracking platform. Used for user identification and linking events to customer records. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "86.025005726085865",
+ "column_distinct_count": "73271",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++0ca@example.com", "++4tj@example.com", "++59d@example.com", "++5ie@example.com", "++621@example.com", "++6p0@example.com", "++9nf@example.com", "++am/@example.com", "++amw@example.com", "++arh@example.com", "++bx5@example.com", "++c6a@example.com", "++czc@example.com", "++dlk@example.com", "++dq3@example.com", "++eco@example.com", "++edg@example.com", "++esv@example.com", "++fdt@example.com", "++gys@example.com", "++hs+@example.com", "++j++@example.com", "++j7k@example.com", "++jqi@example.com", "++jtc@example.com", "++kgt@example.com", "++ltz@example.com", "++mw0@example.com", "++nxj@example.com", "++otm@example.com"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_city",
+ "original_column_name": "event_user_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "City location of the user who triggered the event, derived from IP geolocation or user profile. Used for geographic segmentation and regional funnel analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "89.736630654078269",
+ "column_distinct_count": "10655",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": [" ", " Chantilly", " Diehl", " Los Angeles ", " United States", " ny", "\u0027Ewa Beach", "\u0027s-Gravenhage", "-Miami", ". White Ave Pomo", "00184", "137 Finchley Road", "1561 Kimberton Road", "16 ANDAR C", "1802 Spruce St", "21085", "2315HK", "2329", "25500 - MORTEAU", "2591 SJ Den Haag", "262", "28 Edgar Street Glen Iris", "28 NANTWICH ROAD,MANCHESTER,M14 7AP", "3248", "3321 Marietta Street Rohnert Park, CA 94928", "37934", "3800 Peck Street", "4569 N. Perry Dr.", "4677 Parkridge Drive", "4955 "]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer_source",
+ "original_column_name": "event_referrer_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Marketing source extracted from the referrer URL (e.g., \u0027google\u0027, \u0027facebook\u0027). Used for source-level attribution when UTM parameters are not available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer",
+ "original_column_name": "event_referrer",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "The full referrer URL that brought the user to the page where the event occurred. Contains complete referrer information including query parameters. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "89.798821230069464",
+ "column_distinct_count": "1669",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++ql6lbstb", "+/yzk4zrvi", "+0dbsi82+y", "+2qaad9qkh", "+4scuvdsci", "+588yplzhx", "+5jfjqqdxw", "+6inki4m++", "+72ynx9+f4", "+8vwnpcpmz", "+909zh2wzu", "+bceld1ayq", "+bfhgn79jf", "+bo/gb1dko", "+bsgcfsdjj", "+cbd3v394y", "+ck66zikxa", "+cm+rvrwtc", "+cosxw0vc+", "+dok0wmjkf", "+ebpbfem/w", "+eu/qoyeeg", "+ew7olqxmn", "+eyuubwfmw", "+fwbintfna", "+gbtbsd+v1", "+gdcqm3hqy", "+gmmz3l0tl", "+hdhtnf8kx", "+ilaxmnpig"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer_url",
+ "original_column_name": "event_referrer_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Full referrer URL including query parameters that brought the user to the page. More detailed than event_referrer; used for complete referrer analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Tracking platform emitting the event (elevar, blotout, snowplow, snowplow_ga4, heap, ga4). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["elevar"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_experiment_name",
+ "original_column_name": "event_experiment_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Name of the A/B test or experiment associated with the event. Used to segment events by experiment variant for testing analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_first_name",
+ "original_column_name": "event_user_first_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "First name of the user who triggered the event, when available from tracking platform. Used for personalization and user identification. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.115162458293355",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer_term",
+ "original_column_name": "event_referrer_term",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Search term or keyword extracted from the referrer URL. Used for keyword-level attribution and search query analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_event_name",
+ "original_column_name": "sm_event_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Normalized event name mapped across platforms for consistent funnel analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["add_payment_info", "add_shipping_info", "add_to_cart", "begin_checkout", "generate_lead", "login", "page_view", "purchase", "remove_from_cart", "select_item", "sign_up", "view_cart", "view_item", "view_item_list", "view_search_results"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_country_code",
+ "original_column_name": "event_user_country_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Two-letter ISO country code of the user who triggered the event (e.g., \u0027US\u0027, \u0027CA\u0027, \u0027GB\u0027). Used for international market segmentation and country-level funnel analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "83.299229088834522",
+ "column_distinct_count": "124",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AD", "AE", "AF", "AL", "AM", "AO", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BG", "BH", "BM", "BN", "BR", "BS", "BT", "BZ", "CA", "CH", "CI", "CL", "CM", "CN"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_page_title",
+ "original_column_name": "event_page_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "The title of the web page where the event occurred (from HTML \u003ctitle\u003e tag). Used for page-level funnel analysis and identifying specific landing pages. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.2156726945140544",
+ "column_distinct_count": "3739",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++lyeglaik", "+00zfwezup", "+01oojjq2e", "+07ulynhcd", "+0swuwky4a", "+1qm0uw1+m", "+1siylm676", "+1vnhjxuhn", "+294n9xxfu", "+2py6v0x8k", "+36bp6e2qn", "+3i5dswcy2", "+3szhszv9v", "+47moo/9w5", "+4ist4zp+g", "+4jquel21k", "+4zdxxb9bd", "+5c8s/ow6d", "+5wh15uxm+", "+5wijxnuit", "+6+y3zchlt", "+62ikti4ok", "+6gcroyvww", "+6ihrx8xaa", "+6sfqa+afl", "+7iejo3u34", "+8hdrvncm5", "+94fymyjfr", "+9nshastzj", "+9tcfjkayf"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_last_name",
+ "original_column_name": "event_user_last_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Last name of the user who triggered the event, when available from tracking platform. Used for personalization and user identification. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "90.748523832138318",
+ "column_distinct_count": "22",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Charles", "Daniel", "David", "Elizabeth", "Emily", "James", "Jane", "Jennifer", "Jessica", "John", "Linda", "Lisa", "Mary", "Matthew", "Michael", "Patricia", "Richard", "Robert", "Sarah", "Susan", "Thomas", "William"]
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_currency_code",
+ "original_column_name": "event_currency_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Three-letter ISO 4217 currency code for revenue events (e.g., \u0027USD\u0027, \u0027EUR\u0027, \u0027GBP\u0027). Used for multi-currency revenue tracking and international market analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_referrer_domain",
+ "original_column_name": "event_referrer_domain",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "The domain extracted from the referrer URL that brought the user to the page. Used to identify traffic sources and external sites driving events. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_id",
+ "original_column_name": "sm_utm_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "SourceMedium-generated unique identifier for UTM parameter combinations on this order line. Enables join to UTM attribution data for marketing campaign analysis. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.004022946889055171",
+ "column_distinct_count": "491",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+26ojmerhn", "+albt6ppsb", "+an+n3egvi", "+bckoxwmwy", "+duhqx2hvh", "+fxs8nch1q", "+n4tlrhktj", "+oattuuzup", "+p+ffierdk", "+qftcfvwp+", "+qhjzuxygu", "+wqlqxczzm", "+yjtosstc3", "/1fjx0ertz", "/aqgk8rjdn", "/dhpvxg670", "/krr4oibag", "/lcjpzgwqi", "/lzuz3u3eb", "/nttnrecy0", "/setg/5nkv", "/tyahexl/a", "/uqgtaalo/", "/uwt+l03oy", "04pzwhua2i", "051mcfvyn/", "09dkt1jp+f", "0etdwuajqy", "0fd5ae06ev", "0gx7hcxu0w"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_sub_channel",
+ "original_column_name": "sm_sub_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The sales sub-channel associated with an order, which is derived from the order source name and order tags and factors in manual overrides as defined by the SourceMedium channel mapping configuration sheet. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0047998464049150424",
+ "column_distinct_count": "16",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["0vaq8ipxuc", "giref/lwrh", "gv24ockrwi", "kiyjjju7f5", "lw/tn577i9", "m5ruukjni1", "mybgqh7vvz", "mzse35tdre", "pgya+mnzxt", "sbwysv5ctz"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_tags_csv",
+ "original_column_name": "order_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Comma-separated order-level tags (free-form strings set by merchant/apps). Prefer array fields for exact matching where available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "49.0522392854848",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_title",
+ "original_column_name": "product_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The title of the product.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "62",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Advanced Formula", "Advanced Kit", "Advanced Set", "Basic Set", "Basic Unit", "Classic Edition", "Classic Set", "Combo Pack", "Combo Set", "Complete Bundle", "Complete System", "Deluxe Bundle", "Deluxe Edition", "Elite Bundle", "Elite Series", "Enhanced Kit", "Enhanced Version", "Essential Bundle", "Essential Collection", "Essential Product", "Exclusive Edition", "Exclusive Set", "Full Package", "Full Set", "Luxury Collection", "Master Collection", "Master Set", "Mega Bundle", "Mega Collection", "Original Bundle"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "primary_product_image",
+ "original_column_name": "primary_product_image",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Primary product image URL (display).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The ID of the customer who placed the order.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "12.1468631903268",
+ "column_distinct_count": "85678",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++obe5or2", "+++oygjqva", "++//ladtyl", "++/bfhxibh", "++/ephfq8e", "++0odfm0z1", "++0wixgstj", "++18jy5m9z", "++2pmlds9y", "++2ypmap4c", "++3f7rb07a", "++3ofgbo9h", "++3yuf2kb+", "++4ajmgssa", "++4o8z/i3h", "++4r9kuxpj", "++5fwch7kg", "++5kqolf8p", "++5v3z67ng", "++6awlgicw", "++6c5yjnfi", "++6qkyjv/m", "++87fg1ine", "++8vhgsbke", "++a/uxwxnq", "++bptum8vc", "++brqmxsac", "++bswehump", "++bujah62n", "++c0jcazmw"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_source_medium",
+ "original_column_name": "sm_utm_source_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A concatenation of sm_utm_source and sm_utm_medium. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct) / (none)", "google / cpc", "google / organic", "klaviyo / email", "klaviyo / sms", "meta / paid_social", "tiktok / paid_social"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_state",
+ "original_column_name": "order_shipping_state",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The state of the shipping address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.43207342108441",
+ "column_distinct_count": "712",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "-", "-1", ".", "0", "00", "117 E. Rodrigruez Jr. Ave Brgy Ugong", "722", "8 YEOUI-DAERO, YEONGDEUNGPO DISTRICT, SEOUL", "972", "A Coruña", "AA", "AB", "ACT", "AE", "AGUASCALIENTES", "AK", "AKERSHUS", "AL", "AL AHMEDI - ALI SUBAH AL SALEM", "AL.", "ALABAMA", "ALAJUELA", "ALASKA", "ALBERTA", "ALEXANDRIA", "ANGELES CITY", "ANT", "ANTIOQUIA", "AP"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_order_sequence",
+ "original_column_name": "subscription_order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Whether a subscription order is the first subscription order or a repeat subscription order based on the subscription order index or order tag indicators when an index is not available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016115645874797547",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_sub_order", "one_time_order", "recurring_sub_order"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_zero_party_attribution_source",
+ "original_column_name": "sm_zero_party_attribution_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Attributable source from post‑purchase survey tags (e.g., Fairing/Enquire).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_vendor",
+ "original_column_name": "product_vendor",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The vendor of the product. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "65.720926888883568",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Gateway Trading", "Global Industries", "Standard Products"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_product_variant_key",
+ "original_column_name": "sm_product_variant_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium join key for product variants to related tables.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "271",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+asq4bpdvr", "+meofze43+", "+tghb0qghr", "+ukxyxavka", "+zmz2brors", "/j2dm7vkwg", "/j8kw5cyid", "/ocellizsq", "/xmwtvsoqw", "06kc4/ufen", "0dwdz721fh", "0hex7n3/dv", "0zpmbpdgum", "18w1xxbypo", "1h3qx7jfvk", "1l4iahpo2a", "1lpgcn5w+i", "26yxndo4gq", "2okmsovktk", "2twurv48ma", "2vzixokyiv", "3cgu3dfczf", "3niju+ygvm", "3xmaoezxh8", "4bafl7sv/n", "4rpfju6+zs", "4rzqcmjxd3", "4vdmy9j+i1", "4vswk67lay", "5+dt9ds3gx"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_medium",
+ "original_column_name": "sm_utm_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Last-click UTM medium from the attribution waterfall (Shopify visits/landing/notes -\u003e website events -\u003e GA/GA4 -\u003e referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)", "cpc", "email", "organic", "paid_social", "sms"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_id",
+ "original_column_name": "subscription_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The ID of the subscription.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_tags_csv",
+ "original_column_name": "product_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Comma-separated product tags on the line\u0027s product (free-form; aggregated from product metadata). Use array for exact match; CSV for quick text filters. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "65.795149115606847",
+ "column_distinct_count": "23",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "discount_user", "domestic", "email_subscriber", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sku",
+ "original_column_name": "sku",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The stock keeping unit (SKU) of the product variant.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "210",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+/O", "+1B", "+DP", "+OK", "+OY", "+QC", "+RG", "/1O", "/4T", "/AK", "/HH", "/Y2", "0FJ", "0GB", "0I8", "0S4", "1/9", "10M", "1DC", "1K8", "1MP", "2SF", "2TT", "2VV", "38X", "3P3", "47D", "49Z", "4MG", "4U8"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_id",
+ "original_column_name": "product_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A unique identifier for the product generated by the source system. It can be null for Shopify if the order line data did not contain the product_id populated. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "40.545869905013824",
+ "column_distinct_count": "180",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+4umcswjrz", "+ayl/cffb9", "+hjvv9wv2r", "+pcwjo3bgx", "/3keuvyoh5", "/aoiqmpl4c", "/dloagtgj/", "02nhufsmzw", "060alpbt/d", "0jkrnpzzhh", "0omxvxywvc", "1laiofzdnm", "2ii9xq/ksm", "2my9nuqsrr", "2ue0aftlju", "3hvyz5rfeq", "3jvchbz95k", "4afi1gloor", "4lqezglqe6", "5fexbhp7tu", "5o7yp8et/r", "6bnvut5frm", "6fhhfh8dlr", "6lbuxlrt3f", "6wy6hl3h1j", "7ghps1kvac", "7h2z4d8t5+", "7oj4q/e8ru", "7pwdh8bwvl", "8lkwu0gtio"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_campaign",
+ "original_column_name": "sm_utm_campaign",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Last-click UTM campaign from the attribution waterfall (Shopify visits/landing/notes -\u003e website events -\u003e GA/GA4 -\u003e referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00079865825413305645",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["acquisition_campaign", "anniversary_sale", "back_to_school", "brand_awareness", "bundle_promotion", "clearance_event", "customer_appreciation", "email_blast", "end_of_season", "fall_promo", "flash_sale", "holiday_campaign", "limited_time_offer", "loyalty_program", "mega_sale", "member_exclusive", "new_arrivals", "newsletter_promotion", "product_launch", "referral_campaign", "remarketing_push", "retargeting_ads", "retention_initiative", "seasonal_promo", "social_media_promo", "spring_launch", "summer_sale_2024", "weekend_special", "win_back", "winter_deals"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_number",
+ "original_column_name": "order_number",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The order\u0027s position in the shop\u0027s count of orders. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "49.093576443466411",
+ "column_distinct_count": "57557",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++eh7ptr1", "++0222ysmx", "++0qx2tufq", "++2mjzrcaj", "++2nmjdbui", "++3e1s4rxf", "++3s/weohj", "++4k5v4dcu", "++58dukgma", "++5pbzxypl", "++7jkxgdxw", "++7o1uphct", "++7qkzzla+", "++8cogucvg", "++8xepb62e", "++9vhvdm0q", "++cagir4ox", "++cqboyojp", "++d7hpwitv", "++ddfwsvi4", "++ddn1i4nx", "++diaf/pke", "++drz4tptm", "++dsptbtdc", "++eplvx1uu", "++etjtq+87", "++fkv9ujo9", "++fucn3cvn", "++gaaekx58", "++hmqu3w+l"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_csv",
+ "original_column_name": "customer_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Comma-separated customer tags at order time (free-form; convenience string form of array field). Tags may change over time; value reflects state at order processing time. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "77.2399588053553",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_zip_code",
+ "original_column_name": "order_shipping_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Postal/ZIP code of the shipping address for the order (country-dependent format; not geo-normalized). Combine with country/state for region-based analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.8073595162276046",
+ "column_distinct_count": "45276",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "+051", "+852", "+973", "-", ".", "0", "00", "00-845", "000", "0000", "00000", "000000", "00004", "00012", "00013", "000157", "00019", "00040", "00041", "00042", "00043", "00045", "00052", "00060", "00063", "00071", "00072", "00100", "00118"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_id",
+ "original_column_name": "order_line_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The ID of the order line.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "40.632933766108557",
+ "column_distinct_count": "73729",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++++q9jlfd", "+++wy9li0f", "++/+lzj7g5", "++/goj85ge", "++/grsjge2", "++/pzvcwxi", "++/t9ggrnr", "++04libdlc", "++0b7vdprh", "++16esgrrd", "++1j9xr9yr", "++1u+vo7s9", "++1vhcas/q", "++22lkc94i", "++2mk0eh1q", "++39zjilb+", "++3ia1rngj", "++3qa2mtg3", "++4dhh9k1e", "++4leccgjx", "++4nf8ksft", "++4nhchz3e", "++52guenwd", "++5hudv9mb", "++5v2qhsqx", "++6zmgutuj", "++8/ktrqhw", "++8jrdpkiz", "++8kka1bqd", "++8nbippia"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Sales channel via hierarchy: (1) exclusion tag \u0027sm-exclude-order\u0027 -\u003e excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -\u003e retail, wholesale tags -\u003e wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024050216852788625",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_via_shopify", "online_dtc"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_orders (many:1 - multiple order lines per order).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016057550260132317",
+ "column_distinct_count": "114960",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/xap+mqg", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0ebf0e+m", "++0jv1ijmb", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++3c/x09gr", "++47ptsa/a", "++49mmjnhl", "++4j4h1gve", "++4jmvzdmt", "++5d6l+cbg", "++5tcx/ala", "++6353iqcq", "++6qzsedjz", "++70r/osc4", "++8fwhn0o8", "++8naarfnp", "++a1mdenkf", "++acv2ibby", "++ad66xtkv", "++altzimal", "++ankc4wyk", "++b3bs1py1"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_variant_title",
+ "original_column_name": "product_variant_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The title of the product variant.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "54",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["2X-Large / Black", "2X-Large / Gray", "2X-Large / White", "3X-Large / Black", "3X-Large / Gray", "3X-Large / White", "Extra Small / Black", "Extra Small / Blue", "Extra Small / White", "Large / Blue", "Large / Bronze", "Large / Gold", "Large / Green", "Large / Navy", "Large / Pink", "Large / Silver", "Medium / Black", "Medium / Blue", "Medium / Bronze", "Medium / Gold", "Medium / Gray", "Medium / Green", "Medium / Navy", "Medium / Pink", "Medium / Red", "Medium / Silver", "Medium / White", "One Size / Black", "One Size / Blue", "One Size / Gray"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_sales_channel",
+ "original_column_name": "sm_order_sales_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The sales channel associated with an order, which is derived from the order source name and order tags. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.00080278083280483584",
+ "column_distinct_count": "21",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["aftersell", "amazon.ca", "amazon.com", "amazon_via_shopify", "canal", "draft_orders", "facebook_\u0026_instagram", "gorgias", "online_dtc", "online_store", "recharge", "shop_app", "shopify_app_ios", "si_ca_prod_marketplace", "subscription", "tiktok_shop"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_city",
+ "original_column_name": "order_shipping_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The city, town, or village of the shipping address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.35095591416804217",
+ "column_distinct_count": "16990",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["\tNew Castle", " \tNew Castle", " Arlington", " Baldwin Park", " Beverly Hills, ", " Boca Raton", " Brentwood ", " Bronx", " Brooklyn ", " Brussels", " CLIFTON", " Carmel", " Chantilly", " Chattanooga ", " Chestnut Hill", " Chino Valley", " Clearfield", " Coalville", " Coconut Creek ", " DELRAY BEACH", " Diamond Bar", " FLORIDA", " Gaithersburg", " Greater London", " HARKER HEIGHTS", " Hartford", " Hicksville", " Homer, ", " Hsinchu City 300", " INDIANAPOLIS"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024169963181089418",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_payment_status",
+ "original_column_name": "order_payment_status",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The financial status of an order, which indicates whether the order has been paid. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.004024339203502785",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["authorized", "paid", "partially_paid", "partially_refunded", "pending", "refunded", "voided"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_sequence",
+ "original_column_name": "order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Whether an order is the acquisition order or a repeat order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0056177070125034111",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_order", "repeat_order"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_product_collection_handles_csv",
+ "original_column_name": "order_line_product_collection_handles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Unique, human-readable strings for the collections a product belongs to automatically generated from their titles. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "70.13486236318748",
+ "column_distinct_count": "32",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["back-in-stock", "bestselling-bundles", "classic-collection", "clearance", "complete-kits", "deluxe-collection", "eco-friendly", "exclusive-releases", "fall-collection", "featured-products", "gift-sets", "limited-edition", "limited-stock", "made-to-order", "new-arrivals", "popular-choices", "premium-selection", "recently-added", "sale-items", "seasonal-collection", "specialty-items", "spring-collection", "staff-picks", "starter-kits", "sustainable-products", "top-rated", "travel-size", "trending-now", "vintage-style", "winter-collection"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_type",
+ "original_column_name": "product_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A categorization for the product used for filtering and searching for products.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "65.927541500060585",
+ "column_distinct_count": "9",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Basic Unit", "Enhanced Kit", "Essential Collection", "Full Set", "Performance Kit", "Prime Package", "Standard Unit", "Superior Product"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_country_code",
+ "original_column_name": "order_shipping_country_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The two-letter code (ISO 3166-1 format) for the country of the shipping address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "84",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AD", "AE", "AL", "AR", "AS", "AT", "AU", "BB", "BD", "BE", "BG", "BH", "BM", "BR", "BS", "CA", "CH", "CL", "CN", "CO", "CR", "CU", "CW", "CY", "CZ", "DE", "DK", "EC", "EE", "EG"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_customers (many:1 - multiple order lines per customer).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0016123181103631747",
+ "column_distinct_count": "86048",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cb8c5k5", "+++eczts6a", "++/oys3ymy", "++0ys8prkj", "++0zmq02o0", "++14m2sxd2", "++1k648y7b", "++1xydt8nd", "++2fhrcyos", "++2j7b1tb8", "++2ukk+eyo", "++3edon5z1", "++4cksd2o9", "++4datdb1c", "++4y4+eau/", "++5vp7svy1", "++6cnyry9j", "++6dlxbvsu", "++7ncr62ei", "++7vqpsyow", "++7vu940te", "++86tihdhc", "++a4s8vnru", "++cbdgzxcy", "++do9jdn62", "++dsjyyape", "++e1htkvjd", "++e2p1my6n", "++fgkobaty", "++fzbgen0b"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_country",
+ "original_column_name": "order_shipping_country",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The country of the shipping address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0048134391220287041",
+ "column_distinct_count": "84",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Albania", "American Samoa", "Andorra", "Argentina", "Australia", "Austria", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belgium", "Bermuda", "Brazil", "Bulgaria", "Cambodia", "Canada", "Cayman Islands", "Chile", "China", "Colombia", "Costa Rica", "Croatia", "Cuba", "Curaçao", "Cyprus", "Czech Republic", "Denmark", "Ecuador", "Egypt", "Estonia"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0040178069202706388",
+ "column_distinct_count": "116005",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/52lr43n", "++/nk0i+hs", "++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++19iaug1g", "++1ne8ts5+", "++1rane76v", "++1zslweke", "++22nj24rc", "++2ku8gytz", "++2xxjjoex", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++5yoebovf", "++69bzaknm", "++6h5v8oah", "++7/baoxfj", "++77akmh1u", "++7iv1sads", "++7jzxicxm", "++8dasxxmt", "++8yfuxzom", "++aaiqewlf", "++acmf56kg", "++adj+fbqm"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_discount_codes_csv",
+ "original_column_name": "order_line_discount_codes_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A list of discount codes applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "61.893448234204484",
+ "column_distinct_count": "50",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ANNIVERSARY25", "BFCM60", "BIRTHDAY15", "BUNDLE25", "CLEARANCE40", "CLUB25", "COMEBACK20", "CYBER50", "DELUXE35", "DIAMOND50", "EARLY20", "ELITE25", "EMAIL15", "EXCLUSIVE35", "FALL30", "FIRST10", "FLASH25", "FREESHIP", "GOLD20", "HOLIDAY50", "INSIDER30", "LAUNCH25", "LIMITED50", "LOYALTY15", "MEGA60", "MEMBER20", "MOBILE10", "NEWCUSTOMER25", "NEWYEAR20", "PLATINUM35"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_line_key",
+ "original_column_name": "sm_order_line_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Stable SourceMedium order line key. Unique per line. Key joins: `dim_order_lines` (1:1); `dim_orders` (many:1 via `sm_order_key`). Platform caveat: TikTok Shop coverage may be limited.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "124804",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++dhwmsca", "+++polprfj", "+++pp+mmwu", "+++r4xn4vr", "+++zi4t0dg", "++/1odfshe", "++/6sng+ml", "++/awi1alo", "++/d75odsa", "++/eqkgksx", "++/qwk3b/d", "++/vuz4nk7", "++/zjlgmls", "++0iy+up4n", "++0rnwqvit", "++1op7mygr", "++20lbzkor", "++29ozw5dt", "++2hq6ce3f", "++2ju2krgm", "++2kntr+8x", "++2nu/uwfz", "++2togz+d2", "++2xjqoznp", "++30nbvgwm", "++312ujfin", "++31cywq80", "++31qrnsef", "++356anh6a", "++375xifqg"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_type",
+ "original_column_name": "order_line_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The order line classification, such as a subscription or one-time order, which is derived from order attributes, order tags, or subscription platform data, if a subscription platform has been integrated. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["One-time", "Subscription"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "product_variant_id",
+ "original_column_name": "product_variant_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "A unique identifier for the product variant generated by the source system. It can be null for Shopify if the order line data did not contain the product_variant_id populated.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "41.04715488931889",
+ "column_distinct_count": "263",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+g+qhqdhpc", "+hdftijl+d", "+mxm7hleyd", "+pon+pjshu", "+z/xboipjw", "/4spnrzbwk", "/nsix4n8g5", "/pcso+1kho", "/zetfpit+c", "0e1kabxb1x", "0o54flbcpb", "1/cg+11/p6", "1/iroucw6d", "16ktskp696", "1kdz5jmrsk", "2/rxorh4xe", "29txzmjwiq", "2ekyw0dhev", "2k2tmlmyfh", "2m58o8b3tk", "2wphqzwggs", "37ovr8gk4t", "3e0hc8c6vi", "3m8w8faggy", "3sxjuc+93a", "41ywfvgagp", "4adq1e8kkm", "4cnjlmnikl", "4jvdy4bowb", "4kbv9dlp5y"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_type",
+ "original_column_name": "sm_order_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Stay.ai). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0040063781540212017",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["one_time", "subscription", "subscription_\u0026_one_time"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_source",
+ "original_column_name": "sm_utm_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "Last-click UTM source from the attribution waterfall (Shopify visits/landing/notes -\u003e website events -\u003e GA/GA4 -\u003e referrer). Native UTM on Shopify/Chargebee; marketplaces (Amazon, TikTok Shop, Walmart) lack it. Enriched via GA4, Elevar, Blotout, Snowplow, Heap, Littledata. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_line_product_collection_titles_csv",
+ "original_column_name": "order_line_product_collection_titles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "The titles of collections the product belongs to. Collections are groupings of products that merchants can create to make their stores easier to browse. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "70.1228816962493",
+ "column_distinct_count": "31",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Back in Stock", "Bestselling Bundles", "Classic Collection", "Clearance", "Customer Favorites", "Deluxe Collection", "Eco-Friendly", "Essential Sets", "Fall Collection", "Featured Products", "Gift Ideas", "Gift Sets", "Holiday Shop", "Made to Order", "Modern Line", "Premium Selection", "Professional Series", "Recently Added", "Sale Items", "Seasonal Collection", "Specialty Items", "Spring Collection", "Staff Picks", "Starter Kits", "Summer Collection", "Top Rated", "Travel Size", "Trending Now", "Value Bundles", "Vintage Style"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_tags_csv",
+ "original_column_name": "order_product_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Comma-separated list of product tags from items in the order (free-form, merchant-defined). Tags can be inconsistent across platforms; prefer normalized dimensional attributes when available. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.917634635691655",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_id",
+ "original_column_name": "customer_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The ID of the customer who placed the order.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "8.8161261903763055",
+ "column_distinct_count": "39904",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++oygjqva", "++//ladtyl", "++/bfhxibh", "++/ephfq8e", "++0odfm0z1", "++0wixgstj", "++18jy5m9z", "++2ypmap4c", "++3f7rb07a", "++3ofgbo9h", "++3yuf2kb+", "++4ajmgssa", "++4o8z/i3h", "++4r9kuxpj", "++5kqolf8p", "++5v3z67ng", "++6awlgicw", "++6c5yjnfi", "++6qkyjv/m", "++87fg1ine", "++8vhgsbke", "++a/uxwxnq", "++bptum8vc", "++brqmxsac", "++bswehump", "++bujah62n", "++c0jcazmw", "++c52kocra", "++cklxgx54", "++cshhwtnp"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "primary_order_payment_gateway",
+ "original_column_name": "primary_order_payment_gateway",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The technology or service that securely transmitted payment information between the customer, the business, and the payment processor. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.787508048937541",
+ "column_distinct_count": "12",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affirm", "affirm_pay_over_time", "amazon_marketplace", "amazon_payments", "authorize_net", "bogus", "canal", "cash", "firstdata_e4", "gift_card", "manual", "paypal", "shop_cash", "shopify_installments", "shopify_payments", "tiktok_shop", "truemed"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_valid_order_sequence",
+ "original_column_name": "valid_order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Whether a valid order is the first valid order or a repeat valid order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "24.813713998660418",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_order", "repeat_order"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_name",
+ "original_column_name": "order_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Platform-rendered name (human‑readable or platform‑specific). Not a stable join key.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.15882967607105539",
+ "column_distinct_count": "48108",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cfjzsrf", "++/nk0i+hs", "++/y2j9abi", "++03jqfpbc", "++0i6e8zrt", "++1klwkf0z", "++1zslweke", "++2gvh2bxc", "++2ku8gytz", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++4vstvi1n", "++6ltsxhs9", "++6r9dnc0t", "++7ahc0sep", "++7k6eamy9", "++89i8mrxn", "++8ehtizzg", "++8jmjwi+b", "++8ypchflw", "++9kp/r9wi", "++acmf56kg", "++adj+fbqm", "++aqjjxddy", "++areiftnj", "++b/ahw5de", "++bniszlnq"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cancellation_reason",
+ "original_column_name": "order_cancellation_reason",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The customer\u0027s reason for the order\u0027s cancellation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "98.381515087571216",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["2smkengwc1", "8cuv7qsazk", "fwigzupadk", "ql+s87zxuw", "srqfspapcv", "tsryy4dene"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_content",
+ "original_column_name": "sm_utm_content",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Last-click UTM content from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1424",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++6ps1hkc9", "++cbxa9g2s", "+/9q/q26sx", "+/xiq9mutb", "+03jakftzw", "+2apuj3fau", "+2mwhz0zcx", "+4m0ymx9sr", "+5bplhs4ib", "+5zdqbg5ys", "+6rkoxisfm", "+6y2amsubp", "+9ilkh/bwe", "+ajskfhtqb", "+arpfjskro", "+bxhtczyj1", "+cokok5inb", "+cumg0ommo", "+dzhpot+yl", "+e7hmjcaj/", "+eyz0scoxq", "+eyz6eef1a", "+fendzct2p", "+fno9wmjoe", "+frrvjx78d", "+fu6h1dgru", "+g8fvxl9bw", "+gerfb5ona", "+h/pwa6rq9", "+h3+6acvp+"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_currency_code",
+ "original_column_name": "order_currency_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Three-letter ISO 4217 currency code used to price and settle the order (e.g., USD, CAD, EUR). Multi-currency brands should normalize for FX when comparing revenue across currencies. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["CAD", "USD"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_fbclid",
+ "original_column_name": "sm_fbclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Facebook Click Identifier (FBCLID) from Meta/Facebook ad campaigns, used to track social media conversions. Present when order originated from Facebook/Instagram ad click-through. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1206",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++catl0m0m", "+/0xcwlwsx", "+/2vfwqedj", "+/dh7cxdha", "+1dfxqcsrg", "+2lxyau6iv", "+2m3t1rhhd", "+3a4qylshp", "+3epu/ozt2", "+3tukwlrh1", "+3yqekxrm2", "+5ddqycyxw", "+5tuwdrub6", "+5tz+ve5d+", "+6+dxwa1p2", "+61zqn53cg", "+6auywl9hd", "+79hl6sqar", "+7l72fbyde", "+7p5dmgcvy", "+7pzntfxrr", "+7srovzlqj", "+83fvgktrm", "+8ec97/1ck", "+8viora5op", "+9cqutsbom", "+9ggnpwiuf", "+9phvedvf4", "+9vb3+tn2m", "+9zpkutgk5"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_checkout_id",
+ "original_column_name": "order_checkout_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The ID of the checkout that the order is associated with.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "43.213823074673016",
+ "column_distinct_count": "27052",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++qkxv4hx", "+++ssxtt4d", "++/+hirlad", "++0qpv/vxw", "++2k9bxemk", "++3yq16juh", "++4xnsmxkb", "++4xp+qetm", "++5+mqlo0y", "++5yagrqhd", "++7mhn0qbt", "++8hul48qs", "++aowibze0", "++blmh/xe/", "++emd/v3le", "++gkawndsc", "++gmlceren", "++gqoiul8w", "++hql+gcbv", "++hrop0gwx", "++isitjmnj", "++isy9g+qj", "++iuw0ob05", "++iwgvzceb", "++izklzzvu", "++jdw6yfzu", "++kfiud87a", "++kifipawd", "++la8qpbtu", "++lheowciz"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_zero_party_attribution_source",
+ "original_column_name": "sm_zero_party_attribution_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Attributable source from post‑purchase survey tags (e.g., Fairing/Enquire).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_id",
+ "original_column_name": "sm_utm_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "SourceMedium-generated unique identifier for UTM parameter combinations on this order. Used to link orders to specific marketing campaigns via UTM tracking. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "242",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+26ojmerhn", "+albt6ppsb", "+an+n3egvi", "+bckoxwmwy", "+duhqx2hvh", "+fxs8nch1q", "+n4tlrhktj", "+oattuuzup", "+p+ffierdk", "+qftcfvwp+", "+qhjzuxygu", "+wqlqxczzm", "+yjtosstc3", "/1fjx0ertz", "/aqgk8rjdn", "/dhpvxg670", "/krr4oibag", "/lcjpzgwqi", "/lzuz3u3eb", "/nttnrecy0", "/setg/5nkv", "/tyahexl/a", "/uqgtaalo/", "/uwt+l03oy", "04pzwhua2i", "051mcfvyn/", "09dkt1jp+f", "0etdwuajqy", "0fd5ae06ev", "0gx7hcxu0w"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_id",
+ "original_column_name": "order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Platform order identifier. Not globally unique across stores; pair with `smcid` and `source_system` when needed for scoping.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "47602",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++/52lr43n", "++/nk0i+hs", "++/uwknlxd", "++/y2j9abi", "++03jqfpbc", "++0c+4fulx", "++1ne8ts5+", "++1oscu3i5", "++1rane76v", "++1zslweke", "++2ku8gytz", "++36nb+zit", "++3cilkyrs", "++3mhfe1vw", "++3ttssx7e", "++41w+pjmh", "++4oywszpx", "++5yoebovf", "++6filyhzx", "++6h5v8oah", "++7iv1sads", "++7mmnj5nc", "++8yfuxzom", "++aaiqewlf", "++acmf56kg", "++adj+fbqm", "++areiftnj", "++aw5biowv", "++b/ahw5de", "++bniszlnq"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_country_code",
+ "original_column_name": "order_shipping_country_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The two-letter code (ISO 3166-1 format) for the country of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "71",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["AE", "AR", "AT", "AU", "BB", "BD", "BE", "BG", "BH", "BM", "BR", "BS", "CA", "CH", "CL", "CN", "CO", "CR", "CU", "CW", "CY", "CZ", "DE", "DK", "EC", "EE", "EG", "ES", "FI", "FJ"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_skus_csv",
+ "original_column_name": "order_skus_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "A list of SKUs included in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5513",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++8s9qj94p", "++ex6zlqhb", "++hft6mwha", "++k51eqxjf", "++o2yoevzp", "++tr4ec3xu", "++xjpb843w", "+/6plbpxvt", "+/ewpmofns", "+/fhnhtrnw", "+/hbqjqey/", "+/hivflt9v", "+/oif2gzak", "+/rreg8lah", "+03kcsjwiv", "+0kwhpoh34", "+0o8ocr/0x", "+0uuri+xy9", "+0wdtgigv6", "+11kzeozw0", "+155yriwvx", "+18kicpujb", "+1bcj65vdh", "+1djhsup1w", "+1e+y5x9ph", "+29uacvz4v", "+2gwt6zgjq", "+2ieb2/fit", "+2lj0n91es", "+2tqahg6x1"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_medium",
+ "original_column_name": "sm_utm_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Last-click UTM medium from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)", "cpc", "email", "organic", "paid_social", "sms"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_source_medium",
+ "original_column_name": "sm_utm_source_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Concatenation of source / medium (e.g., \u0027google / cpc\u0027). Shows \u0027(none) / (none)\u0027 when null.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct) / (none)", "google / cpc", "google / organic", "klaviyo / email", "klaviyo / sms", "meta / paid_social", "tiktok / paid_social"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_email_hashed",
+ "original_column_name": "customer_email_hashed",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "A hashed version of the customer\u0027s email address. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.9002046014447362",
+ "column_distinct_count": "39530",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++ETk2SaovO+NzO92Ar+Os7CX+xiy8PT5TA4MIww54\u003d", "+++f3JFVxLc0ECZDdDOHWNpkNgNFAWZ/5BXy3R1V2e8\u003d", "++095Y26PZ5/cELKdEvwlqKqf8MxJp9AI5DD9TOFN9w\u003d", "++0CAJXn4nyuCvXquMaAcqCtnQkX5OHFE0ri3PbEmcs\u003d", "++0xzWhb9hFDwEYUpsi1SylJtteQ/3jd63xeDq9AwA0\u003d", "++1WKQBK3urm/S4RbY65OErwDApRz1X7NjMrr7nUG8I\u003d", "++24vdZQUXGmIkbcxf1PsaTSESMQPnFHJxXegKwsA08\u003d", "++4Bo7Vv5zZd6xJYeEB1mwe79yeSRxv/LQTc+GWl+yw\u003d", "++4Ckq3ViKrkmVieme8GHSlUpzC/7XQH+8L451KZJFk\u003d", "++4TjteEbxmnGvUxGDNxNiPBV/cRuqNp9jNI4Q0imxY\u003d", "++5IeTUNNKikKp/U3UJpXoO/tlPkbebewOnJN6hHRlA\u003d", "++60aygeLxASaaBr0lPi5dg9MQqjAjZhRnSQSDgf9w0\u003d", "++621n2F5KjUoTpQUhqpe9tyKZEmQs2A8kgRZ04WkJs\u003d", "++6A5IYoeh05EiXzA1J6uF3vBgtuVqpiQdS1H/AEW98\u003d", "++8AP6MCumMdPmTFGkyzNqtKLzU5ijnYG9I4THaz6YM\u003d", "++8xmfP6muuoHxyrGncL1kvdlS/VtsjNsTNJrUV2ZG8\u003d", "++9NfcWMocE3IvFOxqWRnHe07LiIRonY54ecpdv3Ruo\u003d", "++A8kue9oVCTiM9V7tccwngqU2EGcP3I+q2uK2aWXEk\u003d", "++ARhEqe4xGuITdO0VVt5qodKHD5+g8iDnaAMioHjYk\u003d", "++BYwv7Q9mQf6pUTE48Y/00oVtCW7iSNvgnPhN/PbpM\u003d", "++C6VWPlcoM/64HzWTh7HWoYFdqH2DMJMgMK3PZjOOg\u003d", "++CIwK9Z83yT3hHc690sPZji9grUoN+GTa1oCiESr00\u003d", "++D2zZv5C9fdVS5BkRw4WA0aS/TsOvIQxXwLJ3mg3/o\u003d", "++E0gkFTfd/gLCv227G1VfEZJdIgjxhjTmhbB3GNRxA\u003d", "++FMqAUP5c8WS6h2PCJUeLtg2o5+FTiwgE3pFQDvRws\u003d", "++Giy/F/AoiBUDYwohjgALMztoTrHJiijXSl4ZsCUyY\u003d", "++HRYJQGYKa0eqjeLvyAwwejPGr6YpvNdpW65pZ3gj0\u003d", "++HXxcJ0fJ1/jMg9WubAmdhCqkmqvQYokh9Bjuaq/ok\u003d", "++ILjftI6aYPAGyA+JNiotpjOa8jm+CswEcm17aqhRQ\u003d", "++JNw7haMv9xHNyK0afOOP0EOuX+ZOGkAroetXypXvU\u003d"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_default_channel",
+ "original_column_name": "sm_default_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Default channel before overrides, from source name and tags: amazon/tiktok_shop/walmart.com; pos/leap -\u003e retail; wholesale tags -\u003e wholesale; otherwise online_dtc. See sm_channel for final channel.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_multi_channel_fulfillment", "amazon_via_shopify", "draft_orders", "exchanged", "excluded", "online_dtc", "partners_/_affiliates", "retail", "wholesale"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_country",
+ "original_column_name": "order_shipping_country",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The country of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "73",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Argentina", "Australia", "Austria", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belgium", "Bermuda", "Brazil", "Bulgaria", "Cambodia", "Canada", "Cayman Islands", "Chile", "China", "Colombia", "Costa Rica", "Croatia", "Cuba", "Curaçao", "Cyprus", "Czech Republic", "Denmark", "Ecuador", "Egypt", "Estonia", "Fiji", "Finland", "France"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_tags_csv",
+ "original_column_name": "customer_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Comma-separated customer tags at time of order; string version of customer_tags_array. Prefer array field for robust matching; CSV can include commas in tag values. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "72.277791846036976",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_landing_page",
+ "original_column_name": "sm_order_landing_page",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The URL for the page where the buyer landed when they entered the shop.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_referrer_domain",
+ "original_column_name": "sm_order_referrer_domain",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Domain derived from order_referring_site.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["example.com"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Originating platform for the record (e.g., Shopify, Amazon, TikTok Shop, Chargebee). Used for platform‑specific behavior and coverage.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "shopify"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_type",
+ "original_column_name": "sm_order_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Order classification (subscription vs one-time) derived from order attributes, tags, or subscription platforms (Shopify Subscription Contract, ReCharge, Skio, Loop, Retextion).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["one_time", "subscription", "subscription_\u0026_one_time"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_sequence",
+ "original_column_name": "order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Customer lifecycle classification: \u0027First Order\u0027 for new customers, \u0027Repeat Order\u0027 for returning customers. Includes all orders (valid + invalid). Use for cohort analysis and retention reporting. See valid_order_index for valid-only ordering.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_order", "repeat_order"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_vendors_csv",
+ "original_column_name": "order_vendors_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Comma-separated list of product vendors in the order, aggregated from line items. Vendor names may vary by platform; use for vendor mix analysis at order level. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "36.186403370857178",
+ "column_distinct_count": "9",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Alpha Distributors", "Apex Wholesale", "Epsilon Brands", "Gateway Trading", "Global Industries", "Junction Supply", "Meridian Corp", "Metro Wholesale", "Noble Suppliers", "Omega Distribution", "Standard Products", "Titan Wholesale", "Universal Brands", "Wholesale Direct", "Zeta Corporation"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_tags_csv",
+ "original_column_name": "order_tags_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Comma-separated list of tags that the shop owner has attached to the order. Use for simple filtering; beware that individual tag values may contain commas.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.909768750918907",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abandoned_cart", "affiliate", "bulk_buyer", "clearance_buyer", "desktop_user", "discount_user", "domestic", "email_subscriber", "express_shipping", "first_purchase", "free_shipping", "full_price", "gift_buyer", "high_value", "influencer", "international", "loyalty_program", "mobile_user", "new_arrival_buyer", "partner", "product_reviewer", "referral_source", "repeat_customer", "seasonal_shopper", "sms_opted_in", "social_media", "standard_shipping", "vip_member", "wholesale", "wishlist_user"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_payment_status",
+ "original_column_name": "order_payment_status",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Financial status of the order (e.g., paid, partially_paid, partially_refunded, authorized, pending, refunded, voided, draft). Platform‑defined.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["authorized", "paid", "partially_paid", "partially_refunded", "pending", "refunded", "voided"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_customer_street_address",
+ "original_column_name": "order_customer_street_address",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Customer\u0027s billing street address associated with the order. May differ from shipping address; use for billing analysis and fraud detection. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "36.066265695895325",
+ "column_distinct_count": "28406",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++05hsjyz9", "++08tzqg7o", "++08ygwvoh", "++2adzwhm+", "++3xuvb8k0", "++4wslrthq", "++5+sslxig", "++5rcnztji", "++62w5ilpg", "++66ojm90y", "++6gecqabe", "++7k9pez7b", "++7to6uzgz", "++8el6mdpe", "++8owdrnsm", "++aruo6zw7", "++avsxi+pt", "++ayjk8ybs", "++bslxra5e", "++co62ssbs", "++dscsk4ki", "++focxc7qm", "++g/ca5gfz", "++golwh9ux", "++hehbboch", "++hv1tptq5", "++iay3ddrj", "++ivci6ame", "++jmkldktn", "++jo9b2edv"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_referring_site",
+ "original_column_name": "order_referring_site",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The URL of the site that referred the customer to the shop.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "73.899796885578866",
+ "column_distinct_count": "306",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_titles_csv",
+ "original_column_name": "order_product_titles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "A list of product titles included in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Advanced Formula", "Advanced Kit", "Advanced Set", "Basic Set", "Basic Unit", "Classic Edition", "Classic Set", "Combo Pack", "Combo Set", "Complete Bundle", "Complete System", "Deluxe Bundle", "Deluxe Edition", "Elite Bundle", "Elite Series", "Enhanced Kit", "Enhanced Version", "Essential Bundle", "Essential Collection", "Essential Product", "Exclusive Edition", "Exclusive Set", "Full Package", "Full Set", "Luxury Collection", "Master Collection", "Master Set", "Mega Bundle", "Mega Collection", "Original Bundle"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Sales channel via hierarchy: (1) exclusion tag \u0027sm-exclude-order\u0027 -\u003e excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -\u003e retail, wholesale tags -\u003e wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_via_shopify", "draft_orders", "exchanged", "excluded", "online_dtc", "partners_/_affiliates", "retail", "wholesale"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_session_browser_type",
+ "original_column_name": "order_session_browser_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Browser type derived from user agent (e.g., chrome, safari, firefox). Coverage depends on website tracking; limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["android", "chrome", "firefox", "ie", "ipad_safari", "iphone_safari", "opera", "safari", "unknown"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_state",
+ "original_column_name": "order_shipping_state",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Province/state of the shipping address; format varies by country and platform.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.6736842105263161",
+ "column_distinct_count": "463",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", " Ave 10,", "-", ".", "00", "117 E. Rodrigruez Jr. Ave Brgy Ugong", "722", "A Coruña", "AA", "AB", "ACT", "AE", "AGUASCALIENTES", "AK", "AL", "ALABAMA", "ALASKA", "ALBERTA", "ALEXANDRIA", "ANGELES CITY", "ANT", "ANTIOQUIA", "AP", "AR", "AREQUIPA", "ARIZONA", "ARKANSAS", "ARizona", "AS", "ATLANTICO"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_processing_method",
+ "original_column_name": "order_processing_method",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Method used to process the order (e.g., \u0027manual\u0027, \u0027direct\u0027, \u0027offsite\u0027). Platform-defined strings; some methods may only appear for specific integrations. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "64.0730616828767",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon_payments"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_sales_channel",
+ "original_column_name": "sm_order_sales_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Raw sales channel from source system (e.g., \u0027TikTok Shop\u0027, \u0027Instagram Shop\u0027). Used as input dimension for sm_channel mapping. See sm_channel for final classification.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "19",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["aftersell", "amazon.ca", "amazon.com", "amazon_removal_order", "amazon_via_shopify", "canal", "draft_orders", "facebook_\u0026_instagram", "faire:_sell_wholesale", "gorgias", "grin_creator_management", "non_amazon", "non_amazon_ca", "non_amazon_us", "online_dtc", "online_store", "point_of_sale", "recharge", "shop_app", "shopify_app_ios", "si_ca_prod_marketplace", "subscription", "tiktok_shop"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_zip_code",
+ "original_column_name": "order_shipping_zip_code",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Postal/ZIP code from the shipping address (alphanumeric, varies by country). Use with country and state to avoid ambiguity; not geo-normalized. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.75660452701708658",
+ "column_distinct_count": "22433",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", " 78260", " 91401", "+051", "+973", "-", ".", "0", "00", "00-845", "000", "0000", "00000", "000000", "00012", "00013", "00019", "00040", "00041", "00042", "00043", "00045", "00052", "00060", "00063", "00071", "00072", "00100", "00118", "00120"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_device_type",
+ "original_column_name": "customer_device_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Device type derived from user agent (e.g., mobile, desktop, tablet). Coverage depends on website tracking; limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "36.323828280500322",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["Unknown", "desktop", "mobile", "tablet"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_customer_key",
+ "original_column_name": "sm_customer_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Stable SourceMedium customer key. Unique per customer. Key joins: `dim_customers` (1:1); `dim_orders`/`obt_orders` (1:many). Platform caveat: TikTok Shop coverage may be limited. Foreign key to obt_customers (many:1 - multiple orders per customer).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "39474",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++cb8c5k5", "++/oys3ymy", "++0ys8prkj", "++0zmq02o0", "++1k648y7b", "++1xydt8nd", "++2fhrcyos", "++2j7b1tb8", "++2ukk+eyo", "++3edon5z1", "++4cksd2o9", "++4datdb1c", "++5vp7svy1", "++6cnyry9j", "++6dlxbvsu", "++7arnsvpq", "++7ncr62ei", "++7vu940te", "++8mjezwhh", "++a4s8vnru", "++cbdgzxcy", "++cols7ohp", "++cytrfifr", "++d1sqsweo", "++do9jdn62", "++e1htkvjd", "++e2p1my6n", "++fgkobaty", "++fzbgen0b", "++gbnjqial"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_product_variant_titles_csv",
+ "original_column_name": "order_product_variant_titles_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "A list of product variant titles included in an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "63",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["2X-Large / Black", "2X-Large / Gray", "2X-Large / White", "3X-Large / Black", "3X-Large / Gray", "3X-Large / White", "Extra Small / Black", "Extra Small / Blue", "Extra Small / White", "Large / Black", "Large / Blue", "Large / Bronze", "Large / Gold", "Large / Gray", "Large / Green", "Large / Navy", "Large / Pink", "Large / Red", "Large / Silver", "Large / White", "Medium / Black", "Medium / Blue", "Medium / Bronze", "Medium / Gold", "Medium / Gray", "Medium / Green", "Medium / Navy", "Medium / Pink", "Medium / Red", "Medium / Silver"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_gclid",
+ "original_column_name": "sm_gclid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Google Click Identifier (GCLID) from Google Ads campaigns, used to track paid search conversions. Present when order originated from Google Ads click-through. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1652",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++qogfezz9", "++taowu9r7", "+/hc2ebgnr", "+/jlakmpor", "+/l1wvpu6d", "+0fkhqit7v", "+0qmebua46", "+0von0kqtd", "+17wttuiqh", "+19f37whlb", "+1noudtotl", "+1o8gjkqw+", "+1pxglf7xo", "+1u62+u+fd", "+1uldn7uzs", "+244bematt", "+2nwysrkj5", "+2rnslmb9o", "+2wz4mvcht", "+2xe3ii6o8", "+3ftxn0a5r", "+3jcszj8yj", "+3k//5v0re", "+3tgjqw6fc", "+3vikb+owo", "+3wkx27cjb", "+4lavoeyqx", "+4obh1dn7f", "+5bd6ee7nt", "+5jo3ia3ud"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_source_name",
+ "original_column_name": "order_source_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Original source reported by the platform (e.g., Shopify sales channel/app name).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "34.342603258186607",
+ "column_distinct_count": "62",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscription_order_sequence",
+ "original_column_name": "subscription_order_sequence",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Subscription lifecycle classification: \u0027First Subscription Order\u0027 for initial subscription purchase, \u0027Repeat Subscription Order\u0027 for renewals. Based on subscription order index when available, otherwise inferred from order tags. Use for subscription cohort analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1st_sub_order", "one_time_order", "recurring_sub_order"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_session_user_agent",
+ "original_column_name": "order_session_user_agent",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Raw user agent string. Used to derive customer_device_type and order_session_browser_type.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "46.016065773191549",
+ "column_distinct_count": "6864",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "[fban/fbios;fbdv/ipad7,5;fbmd/ipad;fbsn/ios;fbsv/13.6.1;fbss/2;fbid/tablet;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone11,6;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone11,8;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/2;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,3;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,5;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/en_us;fbop/5]", "[fban/fbios;fbdv/iphone12,5;fbmd/iphone;fbsn/ios;fbsv/13.6.1;fbss/3;fbid/phone;fblc/fr_fr;fbop/5]", "agent/amazonbuyforme", "go-http-client/2.0", "mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; slcc1; .net clr 2.0.50727; media center pc 5.0; .net clr 1.1.4322; .net clr 3.0.30618; .net clr 3.5.30729; infopath.2; .net4.0c)", "mozilla/5.0 (android 10; mobile; rv:100.0) gecko/100.0 firefox/100.0", "mozilla/5.0 (android 10; mobile; rv:109.0) gecko/119.0 firefox/119.0", "mozilla/5.0 (android 10; mobile; rv:121.0) gecko/121.0 firefox/121.0", "mozilla/5.0 (android 10; mobile; rv:129.0) gecko/129.0 firefox/129.0", "mozilla/5.0 (android 10; mobile; rv:67.0) gecko/67.0 firefox/67.0", "mozilla/5.0 (android 10; mobile; rv:68.0) gecko/68.0 firefox/68.0", "mozilla/5.0 (android 10; mobile; rv:71.0) gecko/71.0 firefox/71.0", "mozilla/5.0 (android 10; mobile; rv:75.0) gecko/75.0 firefox/75.0", "mozilla/5.0 (android 10; mobile; rv:80.0) gecko/80.0 firefox/80.0", "mozilla/5.0 (android 10; mobile; rv:81.0) gecko/81.0 firefox/81.0", "mozilla/5.0 (android 10; mobile; rv:82.0) gecko/82.0 firefox/82.0", "mozilla/5.0 (android 10; mobile; rv:83.0) gecko/83.0 firefox/83.0", "mozilla/5.0 (android 10; mobile; rv:84.0) gecko/84.0 firefox/84.0", "mozilla/5.0 (android 10; mobile; rv:86.0) gecko/86.0 firefox/86.0", "mozilla/5.0 (android 10; mobile; rv:87.0) gecko/87.0 firefox/87.0", "mozilla/5.0 (android 10; mobile; rv:88.0) gecko/88.0 firefox/88.0", "mozilla/5.0 (android 10; mobile; rv:89.0) gecko/89.0 firefox/89.0", "mozilla/5.0 (android 10; mobile; rv:90.0) gecko/90.0 firefox/90.0", "mozilla/5.0 (android 10; mobile; rv:99.0) gecko/99.0 firefox/99.0", "mozilla/5.0 (android 11; mobile; rv:100.0) gecko/100.0 firefox/100.0"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_term",
+ "original_column_name": "sm_utm_term",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Last-click UTM term from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1243",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++qq2wyzut", "+/zhh+87pe", "+0xweipll+", "+1yfkz2ry2", "+2e/uxp3ic", "+2mwhz0zcx", "+2vjnhcp7m", "+3+8mdkonj", "+5crhiqqzx", "+5db33syxo", "+abvlpzwr4", "+alfirsud9", "+bstbbitcu", "+co3l8mzq/", "+cumg0ommo", "+danbp82wr", "+f372ckaac", "+fewfkrtyg", "+fteybjxhk", "+gpkxy/xy/", "+hadikzfxt", "+hdgzzv+ap", "+hqrtt7ynv", "+ibmzinnck", "+imgrphhn3", "+itn6p07bh", "+ivnv8bsdf", "+j0uc75psp", "+jjniw1uiy", "+jk940dpx+"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_campaign",
+ "original_column_name": "sm_utm_campaign",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Last-click UTM campaign from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["acquisition_campaign", "anniversary_sale", "back_to_school", "brand_awareness", "bundle_promotion", "clearance_event", "customer_appreciation", "email_blast", "end_of_season", "fall_promo", "flash_sale", "holiday_campaign", "limited_time_offer", "loyalty_program", "mega_sale", "member_exclusive", "new_arrivals", "newsletter_promotion", "product_launch", "referral_campaign", "remarketing_push", "retargeting_ads", "retention_initiative", "seasonal_promo", "social_media_promo", "spring_launch", "summer_sale_2024", "weekend_special", "win_back", "winter_deals"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_order_key",
+ "original_column_name": "sm_order_key",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Stable SourceMedium order key. Unique per order. Key joins: `obt_order_lines` (1:many via `sm_order_key`); `dim_customers` (many:1 via `sm_customer_key`). Platform caveat: TikTok Shop coverage may be limited. Primary key (grain: one row per sm_order_key). Join to obt_order_lines via sm_order_key (1:many), obt_customers via sm_customer_key (many:1), dim_orders via sm_order_key (1:1).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "47447",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++0mnh6hs", "+++qrg19wg", "++/byhrzn0", "++/uyup3ic", "++/zscdnya", "++04fcfqfz", "++0di6y+uj", "++0jv1ijmb", "++1hay6gzy", "++1rq4thbq", "++2+5zssid", "++3c/x09gr", "++47ptsa/a", "++49mmjnhl", "++4j4h1gve", "++4jmvzdmt", "++5d6l+cbg", "++5nhbevun", "++5tcx/ala", "++6353iqcq", "++6qzsedjz", "++6uqo0c9h", "++6vbygukj", "++8yrbyxu+", "++a1mdenkf", "++ad66xtkv", "++alnmb8pg", "++altzimal", "++b3bs1py1", "++b4eslapi"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_utm_source",
+ "original_column_name": "sm_utm_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Last-click UTM source from attribution waterfall (Shopify visits/landing/notes → website events → GA/GA4 → referrer). Native on Shopify/Chargebee; enriched via website tracking (Elevar, Blotout, Snowplow). Limited for marketplaces.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_number",
+ "original_column_name": "order_number",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Shop-scoped sequence number assigned by the platform. Not globally unique; pair with `smcid` for scoping.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "36.129248986961727",
+ "column_distinct_count": "30606",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++eh7ptr1", "++0222ysmx", "++0qx2tufq", "++1yiotovn", "++2mjzrcaj", "++2nmjdbui", "++3e1s4rxf", "++3s/weohj", "++4k5v4dcu", "++58dukgma", "++5pbzxypl", "++7jkxgdxw", "++7o1uphct", "++7qkzzla+", "++8cogucvg", "++8t6li0yz", "++8xepb62e", "++9vhvdm0q", "++cagir4ox", "++cqboyojp", "++d7hpwitv", "++ddfwsvi4", "++ddn1i4nx", "++diaf/pke", "++drz4tptm", "++dsptbtdc", "++eplvx1uu", "++etjtq+87", "++fcv54lvk", "++fkv9ujo9"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "sm_sub_channel",
+ "original_column_name": "sm_sub_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "Sub-channel from source/tags with config overrides (e.g., Facebook \u0026 Instagram, Google, Amazon FBA/Fulfilled by Merchant).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "14",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/tzi0a9fgc", "0vaq8ipxuc", "3tlnpaa4qx", "dw6kb6cabo", "et3l9c3ehk", "f3jc2brbra", "giref/lwrh", "gv24ockrwi", "kiyjjju7f5", "lw/tn577i9", "m5ruukjni1", "mybgqh7vvz", "mzse35tdre", "pgya+mnzxt", "sbwysv5ctz", "tiqlytmiee", "z6wtlvw+t8"]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_shipping_city",
+ "original_column_name": "order_shipping_city",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "The city, town, or village of the shipping address.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.29515938606847697",
+ "column_distinct_count": "11082",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", "\tNew Castle", " \tNew Castle", " Alexandria", " Ang Mo Kio,", " Arlington", " Baldwin Park", " Beaver Falls", " Beaverton", " Beverly Hills, ", " Boca Raton", " Brentwood ", " Bronx", " Brooklyn ", " Brussels", " CLIFTON", " Cape Coral ", " Carmel", " Chantilly", " Chattanooga ", " Chestnut Hill", " Chino Hills", " Chino Valley", " Clearfield", " Clearwater", " Coalville", " Coatesville", " Coconut Creek ", " Colorado Springs", " Crestview, "]
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_discount_codes_csv",
+ "original_column_name": "order_discount_codes_csv",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "A list of discount codes applied to an order. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "35.148754928627149",
+ "column_distinct_count": "50",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ANNIVERSARY25", "BFCM60", "BIRTHDAY15", "BUNDLE25", "CLEARANCE40", "CLUB25", "COMEBACK20", "CYBER50", "DELUXE35", "DIAMOND50", "EARLY20", "ELITE25", "EMAIL15", "EXCLUSIVE35", "FALL30", "FIRST10", "FLASH25", "FREESHIP", "GOLD20", "HOLIDAY50", "INSIDER30", "LAUNCH25", "LIMITED50", "LOYALTY15", "MEGA60", "MEMBER20", "MOBILE10", "NEWCUSTOMER25", "NEWYEAR20", "PLATINUM35"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Event tracking platform emitting the touchpoint (elevar, snowplow, heap, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["elevar"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "purchase_order_id",
+ "original_column_name": "purchase_order_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Order ID of the purchase event this touchpoint contributed to.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "25487",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++5yoebovf", "++7iv1sads", "++8yfuxzom", "++aaiqewlf", "++fbhty6ci", "++kizvtm95", "++qgldwh/g", "++ryjb6l9l", "++sy3kpa9n", "++tpse6hjn", "++uhny/rqt", "++y4y7xz2i", "++zp09cjnv", "++zsksiyv4", "+/2lkjuj64", "+/3p2dqc3m", "+/47zmbv5l", "+/6yyhclld", "+/800mmve8", "+/8byhwgek", "+/8jqfcna5", "+/8okbafsk", "+/9zvwkfk5", "+/bmij3xe9", "+/db419/k9", "+/fqejpx6e", "+/jj1z8vca", "+/kovwhwxa", "+/mka2hzpj", "+/oyiyoar0"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_event_name",
+ "original_column_name": "sm_event_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Standardized event name (page_view, purchase, add_to_cart, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "9",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["add_payment_info", "add_shipping_info", "add_to_cart", "begin_checkout", "generate_lead", "page_view", "purchase", "view_item", "view_item_list"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_touch_id",
+ "original_column_name": "sm_touch_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Unique identifier for each touchpoint in the customer journey.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "37956",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++vb1/sdm", "++/ghulcpx", "++/yw6elm9", "++0hkoro0k", "++0u4ifskm", "++10dq+njd", "++1hmh9god", "++2obm2af7", "++3iarmnza", "++4esnftzq", "++4mqadyz9", "++4sgo0wzr", "++5i+cyh7b", "++5mmniboz", "++5rzthuwc", "++5u6he07x", "++66dlzfka", "++6igczswv", "++9a7nh1vs", "++9urdcbah", "++akksw+x9", "++aqlkvfls", "++b5xt0xlq", "++bhqjtpxz", "++bi2g5akq", "++btlkmggn", "++bvi2agk3", "++c0y4rk3g", "++c1slzfjw", "++ciaf4l9b"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "purchase_journey_type",
+ "original_column_name": "purchase_journey_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Categorizes the purchase journey based on session count and duration of time elapsed from first touch to purchase",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "90.338254035683946",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["multi_day_multi_session", "same_day_multi_session", "single_session"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_user_id",
+ "original_column_name": "event_user_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "User identifier from the event tracking system for journey attribution.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.050052687038988415",
+ "column_distinct_count": "24759",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++d/eo9q7", "++77sqyped", "++817ewguy", "++ebuty+gy", "++hqp00qpu", "++kyywsl6d", "++okgbvujw", "++r6wnz69v", "++ruqkt8wt", "++tgckmvix", "++ur4cwt8e", "++vve2wn2p", "++wco4xmae", "++xztrh/ru", "++yr78ttzs", "+/bypxmmdg", "+/c/zbjezk", "+/dy8kld6d", "+/gsq6+pbl", "+/hdlvq/vc", "+/k26j/2rq", "+/okjrfeod", "+/p++2s5mr", "+/usx10xia", "+/wbgxh2mu", "+/xm3iyr96", "+/xs2xft74", "+0+p97w/to", "+0/lg5q5so", "+0ddwvf0xc"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_campaign_objective",
+ "original_column_name": "ad_platform_campaign_objective",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Campaign objective set in the ad platform (e.g., conversions, traffic, awareness).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "37.891765309723155",
+ "column_distinct_count": "20",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["0c6jpsmpb/", "2tlycaetwl", "4e6ykcdqqw", "5l2uaw5+7c", "9/ynzmsmtk", "csdnzvov7l", "d9uwtrqoyy", "dajfcqdlb7", "efkytcitjb", "eybbkvq9eg", "hevbcvayvd", "io8gog46uj", "jz88nt81eu", "lwur4ssob9", "mziaamneiv", "o1qlj4kj6r", "stbwwjxhrl", "wr1ypzd11s", "yzobdemydf", "zetfoitcrz"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_image_url",
+ "original_column_name": "ad_creative_image_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "URL to the ad creative image for visual reference and creative analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["https://placehold.co/400/png"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_type",
+ "original_column_name": "ad_campaign_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Campaign type classification from the platform (e.g., search, display, shopping, video).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "4.7802131510154835",
+ "column_distinct_count": "35",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abo", "advantage_plus", "advantage_plus_dpa", "advantage_plus_other", "affiliate", "agency", "cbo", "demand_gen", "direct_mail", "display", "dpa", "influencers", "landing_page", "linear_tv", "meta_ads", "other", "paid_search", "paid_social", "performance_max", "podcast", "programmatic", "rebate", "sales", "search", "search_\u0026_content", "shopping", "smart_performance", "sponsored_brands_\u0026_video", "sponsored_display", "sponsored_products"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_tactic",
+ "original_column_name": "ad_campaign_tactic",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Campaign tactic - defaults to \u0027prospecting\u0027 if null",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affiliate", "automatic_targeting", "brand", "prospecting", "retargeting"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad platform emitting performance data (facebook, google_ads, tiktok, amazon_ads, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affiliate", "amazon_ads", "applovin", "google_ads", "grapevine.ai", "influencers", "meta_ads", "microsoft_ads", "podcast", "postpilot", "producttype(hair_growth_system)product(DemoCo_elite)", "snapchat", "stello_amz", "tiktok", "x_ads"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_id",
+ "original_column_name": "ad_campaign_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Campaign identifier; populated for campaign_level, ad_group_level, and ad_level rows, null for channel_level.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.18546201625990263",
+ "column_distinct_count": "2094",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+1uwkydtyr", "+24v9chkgi", "+37plnkmmo", "+3rnniqmyj", "+6lfwjzcxr", "+7aa+gw4u8", "+b0fooe0xp", "+d3jqjivd0", "+d3wmmyit8", "+exsh3n0bz", "+eyw2cihwc", "+i0xczmnkt", "+jibehzep0", "+k2dvj/tae", "+kmqjqrtwr", "+lavpw6t9b", "+msdzzdnj2", "+n1mjs8bgq", "+ng/ayfucc", "+nt2yafylf", "+ofreafb4r", "+owyk+vutt", "+p/1tyirqt", "+rdlorrnsy", "+tqywmkwst", "+v9cr9ievs", "+xspnqpcav", "+y5tyvqagn", "+yjde0tfpz", "+ymgt4gxmh"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_name",
+ "original_column_name": "ad_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad name from the platform; available for ad_level rows.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "15.10168235142452",
+ "column_distinct_count": "5894",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[google_ads][ad]10030222", "[google_ads][ad]10144608", "[google_ads][ad]10172841", "[google_ads][ad]10320501", "[google_ads][ad]10357133", "[google_ads][ad]10601938", "[google_ads][ad]10704370", "[google_ads][ad]10753767", "[google_ads][ad]10901121", "[google_ads][ad]10967139", "[google_ads][ad]11021108", "[google_ads][ad]11035383", "[google_ads][ad]11052050", "[google_ads][ad]11114796", "[google_ads][ad]11165698", "[google_ads][ad]11170511", "[google_ads][ad]11200655", "[google_ads][ad]11209329", "[google_ads][ad]11232569", "[google_ads][ad]11293296", "[google_ads][ad]11314133", "[google_ads][ad]11358390", "[google_ads][ad]11465849", "[google_ads][ad]11682747", "[google_ads][ad]11929447", "[google_ads][ad]11931320", "[google_ads][ad]11943918", "[google_ads][ad]11959896", "[google_ads][ad]12225590", "[google_ads][ad]12247431"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_group_name",
+ "original_column_name": "ad_group_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad group name from the platform; available for ad_group_level and ad_level rows.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "66.362175624648515",
+ "column_distinct_count": "3466",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+2e/uxp3ic", "+2mwhz0zcx", "+3jr4bukki", "+43fnwuq8o", "+4nprjhucr", "+51vi8cjsy", "+5xdcsbk26", "+7j9mgn/dj", "+87u38hzdj", "+8dak3zifn", "+8m6o7gucf", "+8raw4f+oa", "+8vsvoctg/", "+9tb4qx0m7", "+9wiqoohvj", "+bstbbitcu", "+bszv08z0j", "+byxe9x0zq", "+c6fttt+f2", "+cfjdp5p9g", "+cptbojrgs", "+cumg0ommo", "+cunsdux7a", "+e4zc6wgrv", "+e5g+50gk3", "+efeqyfvef", "+effdnhzon", "+ehym0fe1k", "+etkxrzl6s", "+etwgvmifi"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_group_id",
+ "original_column_name": "ad_group_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad group identifier; populated for ad_group_level and ad_level rows, null for campaign/channel levels.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "66.507069589137785",
+ "column_distinct_count": "3871",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++alfjhdrz", "++cjvsr+wh", "+2diaixehw", "+2unl6hltq", "+3bti21cf9", "+3hhpm/kkk", "+3od51mfup", "+3xxyl3yut", "+5lc+ksfk+", "+5zepc9plt", "+6au973kl7", "+98xr3ayxl", "+9az3pfstv", "+9gpnzowgc", "+9hftmjq7q", "+aankdt62v", "+advunvnb6", "+b9btom4xj", "+brzqlb75y", "+bsvlwyynn", "+c1bmvgx10", "+cfbknfumu", "+cr0psqfr/", "+cu6ou5krr", "+dbughqu80", "+dm0a/ogfm", "+dtd6skmax", "+ehi2jc1qf", "+gsh7mmkpe", "+ii3mwwro/"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_name",
+ "original_column_name": "ad_campaign_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Campaign name from the platform; available for campaign_level and more granular rows.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2073",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[affiliate][campaign]397451", "[affiliate][campaign]413446", "[affiliate][campaign]642222", "[amazon_ads][campaign]100009", "[amazon_ads][campaign]100316", "[amazon_ads][campaign]100522", "[amazon_ads][campaign]100611", "[amazon_ads][campaign]103499", "[amazon_ads][campaign]103840", "[amazon_ads][campaign]104156", "[amazon_ads][campaign]104171", "[amazon_ads][campaign]105500", "[amazon_ads][campaign]105872", "[amazon_ads][campaign]106638", "[amazon_ads][campaign]106844", "[amazon_ads][campaign]107286", "[amazon_ads][campaign]107699", "[amazon_ads][campaign]109511", "[amazon_ads][campaign]110434", "[amazon_ads][campaign]110751", "[amazon_ads][campaign]110793", "[amazon_ads][campaign]110832", "[amazon_ads][campaign]112854", "[amazon_ads][campaign]114797", "[amazon_ads][campaign]115950", "[amazon_ads][campaign]116708", "[amazon_ads][campaign]117259", "[amazon_ads][campaign]118959", "[amazon_ads][campaign]122167", "[amazon_ads][campaign]123214"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Marketing channel (e.g., \u0027Meta\u0027, \u0027Google\u0027, \u0027Impact\u0027)",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "online_dtc"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_id",
+ "original_column_name": "ad_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad-level identifier; populated only for ad_level waterfall rows, null for higher aggregation levels.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "15.129593717058412",
+ "column_distinct_count": "23694",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[google_ads]10005879", "[google_ads]10015512", "[google_ads]10017486", "[google_ads]10017637", "[google_ads]10022265", "[google_ads]10023055", "[google_ads]10023452", "[google_ads]10027582", "[google_ads]10032641", "[google_ads]10034772", "[google_ads]10039023", "[google_ads]10039086", "[google_ads]10041257", "[google_ads]10042786", "[google_ads]10044322", "[google_ads]10046868", "[google_ads]10048382", "[google_ads]10060377", "[google_ads]10066085", "[google_ads]10066453", "[google_ads]10072955", "[google_ads]10074260", "[google_ads]10083388", "[google_ads]10084825", "[google_ads]10094714", "[google_ads]10100427", "[google_ads]10107329", "[google_ads]10123580", "[google_ads]10128569", "[google_ads]10128610"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_title",
+ "original_column_name": "ad_creative_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Ad creative title text for ad-level identification and analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "80.20786444601633",
+ "column_distinct_count": "5511",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++6ztkmrpk", "++vmootjg5", "+/2anssqcs", "+/g7f1hfav", "+/ofwschvu", "+/x+y7hsjl", "+/z7gyourl", "+/zdl115mg", "+/zmf2k6wx", "+05bxvjnep", "+0um2hffff", "+0wmnz/1we", "+15efjzfhk", "+1qiyhftbx", "+26oqmcytk", "+27waoglqo", "+2aeius3zx", "+2j5kemdry", "+2nakwnnb/", "+3lyluazvt", "+3uivmaiij", "+3win9fiav", "+3yhk+p2e6", "+4d9keu+6/", "+4dohqmt9s", "+4me7fota8", "+4nrbbbgif", "+4vhlpqilm", "+5gydpvvda", "+5pury7zq7"]
+}, {
+ "table_name": "rpt_ad_attribution_performance_daily",
+ "dataset_name": "sm_experimental",
+ "table_type": "Report",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "waterfall_level",
+ "original_column_name": "waterfall_level",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "This model combines ad-level performance data with attribution metrics. Implements true waterfall attribution hierarchy: - Ad level (when ad_id is present) - Ad group level (when ad_group_id is present but no ad_id) - Campaign level (when ad_campaign_id is present but no ad_group_id) - Channel level (when all granular IDs are null) The waterfall ensures each dollar flows to the most granular level available and matches rpt_ad_performance_daily totals exactly. Brand campaigns receive zero attribution. ",
+ "column_description": "Level in the waterfall hierarchy: ad_level, ad_group_level, campaign_level, or channel_level",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["bb4i1x9qa4", "etnhpxtak2", "iyqjiix0xy", "tn80zeevwa"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_id",
+ "original_column_name": "ad_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The unique identifier for the ad. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "42.527727783161815",
+ "column_distinct_count": "26434",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[google_ads]10005879", "[google_ads]10015512", "[google_ads]10017486", "[google_ads]10017637", "[google_ads]10022265", "[google_ads]10023055", "[google_ads]10023452", "[google_ads]10027582", "[google_ads]10032641", "[google_ads]10034772", "[google_ads]10038670", "[google_ads]10039023", "[google_ads]10039086", "[google_ads]10041257", "[google_ads]10042786", "[google_ads]10046868", "[google_ads]10048382", "[google_ads]10060377", "[google_ads]10066085", "[google_ads]10066453", "[google_ads]10072955", "[google_ads]10074260", "[google_ads]10083388", "[google_ads]10084825", "[google_ads]10094714", "[google_ads]10100427", "[google_ads]10107329", "[google_ads]10123580", "[google_ads]10128569", "[google_ads]10128610"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_body",
+ "original_column_name": "ad_creative_body",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The body copy of the ad creative used for the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "92.07444888933253",
+ "column_distinct_count": "559",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+/c0fdvitj", "+asuhrydtz", "+ebgwce+wx", "+mhtm+pqev", "+nlldv62no", "+ob1bknoza", "+r62kc4qcb", "+szmhtti3z", "+wfvqwup/s", "+yf2qdufco", "/2nskka/ly", "/curj6ofo2", "/dxplmurch", "/etltk1gxk", "/fa6xedyd7", "/fz1ldidbv", "/rocti5zkn", "/rv7zg6i05", "/rznrtqnvx", "/tbmqwlwzy", "04v1feelb2", "08pseyjgub", "09zxbxddgx", "0cqljvrfbv", "0cuhcqpnsu", "0fmsfwxowq", "0jgwmkjzpl", "0l8qjhbz73", "0lkvdr1skg", "0plpw14iy+"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_campaign_objective",
+ "original_column_name": "ad_platform_campaign_objective",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The objective of the campaign that is associated with the ad, such as \"maximize conversion\" or \"target impression share\" (the campaign objective will vary by advertising platform). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "56.720412534464394",
+ "column_distinct_count": "20",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["0c6jpsmpb/", "2tlycaetwl", "4e6ykcdqqw", "5l2uaw5+7c", "9/ynzmsmtk", "csdnzvov7l", "d9uwtrqoyy", "dajfcqdlb7", "efkytcitjb", "eybbkvq9eg", "hevbcvayvd", "io8gog46uj", "jz88nt81eu", "lwur4ssob9", "mziaamneiv", "o1qlj4kj6r", "stbwwjxhrl", "wr1ypzd11s", "yzobdemydf", "zetfoitcrz"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sub_channel",
+ "original_column_name": "sub_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "Sub-channel classification for the ad, typically derived from campaign naming or ad platform specifics. Provides additional granularity beyond sm_channel for channel-specific analysis (e.g., Affiliate, Brand, Retargeting). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "10",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["0xjhktvjsn", "47deqpj8hb", "dgtun1biml", "iunrbe2ung", "j6cj1ik4tg", "lrkdsi7poy", "msfu3trprp", "pljfvltmev", "t2tnwoq3e3", "xyzjrzoxb8"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_instagram_url",
+ "original_column_name": "ad_creative_instagram_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The URL of the ad creative as it appears on Instagram. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["https://placehold.co/400/png"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_facebook_url",
+ "original_column_name": "ad_creative_facebook_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The URL of the ad creative as it appears on Facebook. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["https://placehold.co/400/png"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The advertising source system used to deliver the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "15",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affiliate", "amazon_ads", "applovin", "google_ads", "grapevine.ai", "influencers", "meta_ads", "microsoft_ads", "podcast", "postpilot", "producttype(hair_growth_system)product(DemoCo_elite)", "snapchat", "stello_amz", "tiktok", "x_ads"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_title",
+ "original_column_name": "ad_creative_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The title of the ad creative used for the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "85.216622797748272",
+ "column_distinct_count": "6926",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++6ztkmrpk", "++vmootjg5", "+/2anssqcs", "+/g7f1hfav", "+/ofwschvu", "+/x+y7hsjl", "+/z7gyourl", "+/zdl115mg", "+/zmf2k6wx", "+05bxvjnep", "+0um2hffff", "+0wmnz/1we", "+15efjzfhk", "+1qiyhftbx", "+26oqmcytk", "+27waoglqo", "+2aeius3zx", "+2j5kemdry", "+2nakwnnb/", "+3lyluazvt", "+3uivmaiij", "+3win9fiav", "+3yhk+p2e6", "+4d9keu+6/", "+4dohqmt9s", "+4me7fota8", "+4nrbbbgif", "+4vhlpqilm", "+5gydpvvda", "+5pury7zq7"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The sales channel associated with the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "online_dtc"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_name",
+ "original_column_name": "ad_campaign_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The name of the campaign that is associated with the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2497",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[affiliate][campaign]187864", "[affiliate][campaign]268449", "[affiliate][campaign]350929", "[affiliate][campaign]397451", "[affiliate][campaign]413446", "[affiliate][campaign]642222", "[affiliate][campaign]764772", "[affiliate][campaign]905537", "[amazon_ads][campaign]100009", "[amazon_ads][campaign]100316", "[amazon_ads][campaign]100522", "[amazon_ads][campaign]100611", "[amazon_ads][campaign]101508", "[amazon_ads][campaign]103499", "[amazon_ads][campaign]103840", "[amazon_ads][campaign]104156", "[amazon_ads][campaign]104171", "[amazon_ads][campaign]104404", "[amazon_ads][campaign]104885", "[amazon_ads][campaign]105500", "[amazon_ads][campaign]105610", "[amazon_ads][campaign]105872", "[amazon_ads][campaign]106638", "[amazon_ads][campaign]106844", "[amazon_ads][campaign]107286", "[amazon_ads][campaign]107699", "[amazon_ads][campaign]109511", "[amazon_ads][campaign]109946", "[amazon_ads][campaign]110434", "[amazon_ads][campaign]110751"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_link_params",
+ "original_column_name": "ad_creative_link_params",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The URL parameters used in the ad creative link. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "88.276764411606251",
+ "column_distinct_count": "207",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+/yl0egxz+", "+3nwzarofe", "+gkaq5tstr", "+hwqzev+ae", "/+x1p2cxue", "/e5wsglrve", "/vrn1kx6mm", "09w4uzhse/", "0bs999ge0g", "0l0wcwjnde", "0orxqrt4ms", "0uuu5gl3go", "0wa8nr0upc", "0x3wh0apvu", "1iqus5vprs", "1s68kkew6b", "1stoepjnj2", "1xe8d0+itl", "26brok/5bd", "2eg9jga20c", "2lijyvk5sr", "2n93fbpaqd", "2tplra3uac", "32he+m4pv3", "3fabrtvwed", "3ieg3xp1dr", "3tfzi3jbqd", "3xjegg9ss0", "41qrzlt5zm", "4gtdk2u7qe"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_group_name",
+ "original_column_name": "ad_group_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The name of the ad group that contains the ad. Provides human-readable identification for ad set organization within campaigns. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "71.514368223847455",
+ "column_distinct_count": "3807",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+2e/uxp3ic", "+2mwhz0zcx", "+3jr4bukki", "+43fnwuq8o", "+4nprjhucr", "+51vi8cjsy", "+5xdcsbk26", "+7j9mgn/dj", "+87u38hzdj", "+8dak3zifn", "+8m6o7gucf", "+8raw4f+oa", "+8vsvoctg/", "+9tb4qx0m7", "+9wiqoohvj", "+antnj3kpp", "+bstbbitcu", "+bszv08z0j", "+byxe9x0zq", "+c6fttt+f2", "+cfjdp5p9g", "+cumg0ommo", "+cunsdux7a", "+e4zc6wgrv", "+e5g+50gk3", "+efeqyfvef", "+effdnhzon", "+ehym0fe1k", "+etkxrzl6s", "+etwgvmifi"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_account_id",
+ "original_column_name": "ad_account_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The unique identifier for the ad account that is associated with the ad. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.24226762496971657",
+ "column_distinct_count": "12",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["6ed5iwh4pr", "9n3+4gstrk", "d2hlzemmic", "fejgeicvii", "gjrbyvl7l+", "gqf5akjhby", "hmnnrn+zdw", "rbd+acxmep", "saynhugvjq", "skwyyoefbi", "xanob/nuy/", "xurv/bbrb5"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_call_to_action_type",
+ "original_column_name": "ad_creative_call_to_action_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The type of call-to-action used in the ad creative, such as \"order now\" or \"sign up\" (the call to action type will vary by advertising platform). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "94.724361861428363",
+ "column_distinct_count": "6",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["GET_OFFER", "LEARN_MORE", "MESSAGE_PAGE", "NO_BUTTON", "SHOP_NOW", "SIGN_UP", "VIEW_INSTAGRAM_PROFILE", "WATCH_MORE"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_id",
+ "original_column_name": "ad_campaign_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The unique identifier for the campaign that is associated with the ad. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.22727535818056238",
+ "column_distinct_count": "2476",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+1uwkydtyr", "+24v9chkgi", "+37plnkmmo", "+3rnniqmyj", "+6lfwjzcxr", "+7aa+gw4u8", "+b0fooe0xp", "+d3jqjivd0", "+d3wmmyit8", "+ehzkhqmtp", "+exsh3n0bz", "+eyw2cihwc", "+i0xczmnkt", "+itsnixmm2", "+jibehzep0", "+k2dvj/tae", "+kmqjqrtwr", "+lavpw6t9b", "+msdzzdnj2", "+n1mjs8bgq", "+ng/ayfucc", "+nt2yafylf", "+ofreafb4r", "+owyk+vutt", "+p/1tyirqt", "+rdlorrnsy", "+rkmfr9jr8", "+t5ciyh4lr", "+tqywmkwst", "+v9cr9ievs"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_name",
+ "original_column_name": "ad_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The name of the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "42.4235903505199",
+ "column_distinct_count": "6748",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[applovin][ad]16014325", "[applovin][ad]23143988", "[applovin][ad]41421801", "[applovin][ad]60809502", "[applovin][ad]81454601", "[google_ads][ad]10030222", "[google_ads][ad]10144608", "[google_ads][ad]10172841", "[google_ads][ad]10320501", "[google_ads][ad]10357133", "[google_ads][ad]10601938", "[google_ads][ad]10704370", "[google_ads][ad]10753767", "[google_ads][ad]10901121", "[google_ads][ad]10967139", "[google_ads][ad]11021108", "[google_ads][ad]11035383", "[google_ads][ad]11052050", "[google_ads][ad]11114796", "[google_ads][ad]11165698", "[google_ads][ad]11170511", "[google_ads][ad]11200655", "[google_ads][ad]11209329", "[google_ads][ad]11232569", "[google_ads][ad]11293296", "[google_ads][ad]11314133", "[google_ads][ad]11358390", "[google_ads][ad]11465849", "[google_ads][ad]11682747", "[google_ads][ad]11929447"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_image_url",
+ "original_column_name": "ad_creative_image_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The URL of the image used in the ad creative. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["https://placehold.co/400/png"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_group_id",
+ "original_column_name": "ad_group_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The unique identifier for the ad group that contains the ad. Used to group related ads within a campaign for organizational and reporting purposes. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "71.420198429071064",
+ "column_distinct_count": "4235",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++alfjhdrz", "++cjvsr+wh", "+2diaixehw", "+2unl6hltq", "+3bti21cf9", "+3hhpm/kkk", "+3od51mfup", "+3xxyl3yut", "+5lc+ksfk+", "+5zepc9plt", "+6au973kl7", "+98xr3ayxl", "+9az3pfstv", "+9gpnzowgc", "+9hftmjq7q", "+aankdt62v", "+advunvnb6", "+b9btom4xj", "+brzqlb75y", "+bsvlwyynn", "+c1bmvgx10", "+cfbknfumu", "+cr0psqfr/", "+cu6ou5krr", "+dbughqu80", "+dm0a/ogfm", "+dtd6skmax", "+ehi2jc1qf", "+gsh7mmkpe", "+ii3mwwro/"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_tactic",
+ "original_column_name": "ad_campaign_tactic",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The tactic of the campaign derived from campaign naming conventions. Possible values are \"Prospecting\", \"Retargeting\", and \"Brand\". Default is \"Prospecting\". ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["affiliate", "automatic_targeting", "brand", "prospecting", "retargeting"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_id",
+ "original_column_name": "ad_creative_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The unique identifier for the ad creative that is associated with the ad. ",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "87.80065688770604",
+ "column_distinct_count": "7493",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++hrlqhny", "++3p2jq9ke", "++jwcaznxn", "++k5vsbi3m", "++npscymcg", "+/bn2vn7d2", "+/np3dchaa", "+/nw+wuoju", "+/vkzf9+0q", "+0bfky0zdv", "+1rifx7zl+", "+1y4gydoep", "+26zma71ha", "+2azbtlmed", "+3wy83c8f0", "+3wzlwtt1k", "+3zw6iltog", "+4f9n7b20i", "+4vcanyt7i", "+50wcrlekn", "+5htjwp6vj", "+5pdlqsiz9", "+5xcggzh8f", "+6991f1sxw", "+6awmezmhp", "+6dsvp6ydz", "+79/6anyj2", "+7fvt2kpmk", "+7ijzvvpxw", "+8cbjbqnyr"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_campaign_type",
+ "original_column_name": "ad_campaign_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The type of campaign that is associated with the ad, such as reach, discovery, search, display, or video (this campaign type will vary by advertising platform). ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.5201519859705259",
+ "column_distinct_count": "35",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["abo", "advantage_plus", "advantage_plus_dpa", "advantage_plus_other", "affiliate", "agency", "cbo", "demand_gen", "direct_mail", "display", "dpa", "influencers", "landing_page", "linear_tv", "meta_ads", "other", "paid_search", "paid_social", "performance_max", "podcast", "programmatic", "rebate", "sales", "search", "search_\u0026_content", "shopping", "smart_performance", "sponsored_brands_\u0026_video", "sponsored_display", "sponsored_products"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_account_name",
+ "original_column_name": "ad_account_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The name of the ad account that is associated with the ad. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.21849599359899061",
+ "column_distinct_count": "11",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["1rdilil+ll", "6lmpmmuumt", "cjeb24hc7u", "eceqd11dzj", "ghhmstdmhn", "nyt1nbccfq", "szdj8mvbxx", "t+jtbaa/lg", "tqibs16jou", "wwhdk2k1dv", "xuzk2gfle6"]
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_creative_thumbnail_url",
+ "original_column_name": "ad_creative_thumbnail_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "The URL of the thumbnail image used in the ad creative. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "89.372105289499927",
+ "column_distinct_count": "4787",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++7wwr3z5x", "++t1lgydxj", "+/pvq71l3+", "+/rws1ho0k", "+/zrz6y4vn", "+0a6ba3isb", "+0wh9ja8cv", "+15f++7opu", "+1fndbdhh2", "+1ob1t0qfx", "+1wbkpizcr", "+2b447+a+c", "+2l+lglxj5", "+32yjekqwl", "+4819ypa2v", "+5xry+gmy4", "+6ihvhstg8", "+6irvkeycf", "+7rjs5xinz", "+7sppx56hc", "+89n6snefl", "+8dpjk0e5o", "+9mwoborqc", "+9skoh949w", "+anm2vmbgb", "+arykzv1kr", "+azqkdx4sl", "+bnwonatmv", "+bsmyzxqoq", "+cpiuonl9s"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_filter_name_filter_value_id",
+ "original_column_name": "cohort_filter_name_filter_value_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Unique identifier for the cohort grouping without time dimension (name/value composite).",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "84163",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++2/qyiuw", "++3g8w1goo", "++3m5z5nl6", "++4grs8ist", "++8brrvwxn", "++day3kqdb", "++dz0kvsnr", "++ejgqwjeo", "++eyodjtwe", "++fe+racfk", "++fwg/utbr", "++gdlaph7x", "++hrztyge0", "++it2lab+9", "++j/rze7z5", "++mugabgtd", "++n/ymnqbf", "++nvj9kuqg", "++pvcpvqzv", "++q6gdlaet", "++ujqvkcb8", "++x6rh1bx3", "++xdb6p6jy", "++yocgvbz/", "++zsj6xsdc", "+//gzufp8d", "+/0o53sxi2", "+/1qgqwcqr", "+/5qwu8wps", "+/6al8uoqj"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "months_since_first_order_name",
+ "original_column_name": "months_since_first_order_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Label for months since first valid purchase (e.g., \u0027Acquisition Month\u0027, \u0027+1\u0027).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "115",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+bwpozr2jt", "/cbosqcnwl", "0m4egu16f+", "1qb7jdkwcl", "23iw4ckhst", "24cfoiyq+t", "4y4xg7tfwf", "8d5buku6sg", "9h+mcyubv7", "9np124mbdp", "9wjpnzwaz1", "a97btjeanc", "abihdxq4hb", "akitsw0b/j", "axwlgs29pw", "b4ash9dyhj", "bd7nny7ewy", "caw4rsofx/", "cle/zkqhqg", "crn91gjdnq", "dbbflyezf5", "dfgup5cidx", "dn2jux5tt1", "dy8nurdunq", "e5hm31zhgf", "eekjtf8hxb", "eeps0g+t+6", "eff7yke44y", "esj1zylmpo", "exqf7wntlf"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "acquisition_order_filter_dimension",
+ "original_column_name": "acquisition_order_filter_dimension",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Dimension name used to group cohorts by first valid purchase attribute (e.g., sm_channel).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "7",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["campaign", "discount_code", "no_filters", "order_type_(sub_vs._one_time)", "source/medium", "sub_channel", "zero_party_attribution"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Acquisition channel for cohort segmentation (mapped from channel field in parent model).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "online_dtc"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "cohort_filter_name_filter_value_month_id",
+ "original_column_name": "cohort_filter_name_filter_value_month_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Unique identifier for the cohort row (name/value/month composite).",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "352373",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["+++976ptof", "+++9kttcbf", "+++d+lapks", "+++dr1swh2", "+++fd9kyxp", "+++kw0yllu", "+++nkgv2vy", "+++rjcobes", "+++vxdqwn4", "+++ywjblgj", "++//xypiz0", "++/63xy6bz", "++/c6crpri", "++/f0k+xct", "++/kjbre7d", "++/nsf5std", "++/wdaux2d", "++/wv6atvs", "++01ec2xrf", "++04hbniod", "++09q1pd8v", "++0aamkjbv", "++0drbqgpn", "++0eg3mcad", "++0i+vx4mk", "++0jealj1g", "++0jznemre", "++0m849ysj", "++0mcybu5a", "++0nytqhcw"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_order_line_type",
+ "original_column_name": "sm_order_line_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Order line type segmentation (mapped from slice field in parent model).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["all_orders", "one_time_orders_only", "subscription_orders_only"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_cohort_ltv_by_first_valid_purchase_attribute_no_product_filters",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Unknown",
+ "primary_use_case": "Reporting",
+ "column_name": "acquisition_order_filter_dimension_value",
+ "original_column_name": "acquisition_order_filter_dimension_value",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Cohort LTV analysis by first valid purchase attributes (channel, campaign, source) with no product filters. Grain: One row per cohort_filter_name_filter_value_month_id. Date field: cohort_month. Critical filters: acquisition_order_filter_dimension for cohort grouping; cohort_month for time selection. Key joins: none; drill down to obt_orders using (cohort_month, attribute filters). ",
+ "column_description": "Dimension value for the cohort grouping.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-10-01",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "21064",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["", " FMGN-ZVAM-IFT8 and $50 Off for Shipping Fee", " Free Upgrade, FREE - LIMITED TIME OFFER, manual, Add-on Discount, SAVE400", " Free Upgrade, manual, Add-on Discount, CHRISGIBSON", " K4VT-AMZ6-B6TP, Int\u0027l Shipping discount, Int\u0027l Shipping discount", " K4VT-AMZ6-B6TP, SAVE15", " Save More - Discount Tiers: 10/20/30% Off, 10142018 - Gummy - Buy More", " ps11_2_male_young_1 _purchase_lookalike_vid_testimonial_shai_longad", " ps14_2_female_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowin6months", " ps14_2_male_old_1 _purchase_lookalike_vid_commercial_longadtext_regrowin6months", " ps14_2_male_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowin6months", " ps15_3_female_young_1 _purchase_lookalike_vid_commercial_longadtext__regrowin25minutes", " ps15_3_male_old_1 _purchase_lookalike_vid_commercial_longadtext_regrowin25minutes", " ps15_3_male_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowin25minutes", " ps15_3_male_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowyourhairormoneyback", " ps16_4_female_old_1 _purchase_lookalike_vid_commercial_longadtext_defeathairloss", " ps16_4_female_young_1 _purchase_lookalike_vid_commercial_longadtext_defeathairloss", " ps16_4_male_old_1 _purchase_lookalike_vid_commercial_longadtext_defeathairloss", " ps16_4_male_old_1 _purchase_lookalike_vid_commercial_longadtext_tiredofbalding", " ps16_4_male_young_1 _purchase_lookalike_vid_commercial_longadtext_defeathairloss", " ps17_5_female_old_1 _purchase_lookalike_vid_commercial_longadtext_regrowhairfast", " ps17_5_female_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowhairfast", " ps17_5_male_old_1 _purchase_lookalike_vid_commercial_longadtext_regrowhairfast", " ps17_5_male_young_1 _purchase_lookalike_vid_commercial_longadtext_regrowhairfast", " ps20_2_female_old_1 _purchase_lookalike_sin_textvariation2_hairgrowthresults", " rt11_2_male_young_vid_views_low_vid_testimonial_shai_longad", " rt12_2_male_old_vid_views_low_vid_testimonial_jorge_longad", " rt13_2_female_old_vid_views_low_vid_testimonial_frank_longad", " rt13_2_male_old_vid_views_low_vid_testimonial_frank_longad", " rt25_sin_regrowyourhairchat"]
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_channel",
+ "original_column_name": "sm_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Sales channel via hierarchy: (1) exclusion tag \u0027sm-exclude-order\u0027 -\u003e excluded; (2) config sheet overrides; (3) default logic (amazon/tiktok_shop/walmart.com, pos/leap -\u003e retail, wholesale tags -\u003e wholesale, otherwise online_dtc). Note: excluded channel is omitted from Executive Summary and LTV.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "8",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["amazon", "amazon_via_shopify", "draft_orders", "exchanged", "excluded", "online_dtc", "partners_/_affiliates", "retail", "wholesale"]
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_sub_channel",
+ "original_column_name": "sm_sub_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "Sub-channel from source/tags with config overrides (e.g., Facebook \u0026 Instagram, Google, Amazon FBA/Fulfilled by Merchant).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "21",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/tzi0a9fgc", "0vaq8ipxuc", "3tlnpaa4qx", "7sy38hyoc7", "9ippfebhxy", "dw6kb6cabo", "et3l9c3ehk", "ezc5ydencc", "f3jc2brbra", "giref/lwrh", "gv24ockrwi", "kiyjjju7f5", "lw/tn577i9", "m5ruukjni1", "mybgqh7vvz", "mzse35tdre", "ohbmdjjrxy", "pgya+mnzxt", "pm8+8wytec", "sbg688kh0x", "sbwysv5ctz", "sjpqhdna3e", "wvrdlnkbxq", "y7dkbr3kvj", "z6wtlvw+t8"]
+}, {
+ "table_name": "rpt_executive_summary_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Executive Reporting",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily KPI aggregation for executive reporting and dashboards (revenue, ROAS, profit, targets). Grain: One row per (smcid, sm_channel, sm_sub_channel, date). Date field: date. Critical filters: sm_channel for channel-specific KPIs; date for time windows. Key joins: none; drill down to obt_orders using (date, sm_channel) filters. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_utm_term",
+ "original_column_name": "event_utm_term",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "UTM term parameter for paid search keyword tracking.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "46.432135107555226",
+ "column_distinct_count": "7708",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++rndyamyy", "++tgpf9vie", "++u2agbo+y", "+/biamosfy", "+/fa2dgdnc", "+/ktukdctv", "+/wyacqtzn", "+0anec+pds", "+0fc3wumak", "+0zylcd7wy", "+18dehlrnd", "+27izfzlnh", "+2mwhz0zcx", "+2tgwk88gf", "+2vjnhcp7m", "+36kjy0s11", "+3et4dkquh", "+3g7zczcg/", "+3q5oeuvmv", "+3s29dl4cf", "+584vvezrh", "+5qfpbi/ke", "+5vnwtgox7", "+6a3zp6gck", "+6udxvgd6/", "+76c2uvrb9", "+7jt/x2zj+", "+7ppb+sp+h", "+7sry7t+ha", "+7ut9s+3sp"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_page_path",
+ "original_column_name": "event_page_path",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "URL path component for page-level aggregation.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "36839",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["/", "/-finalday", "//", "//a/account/quick-action/reactivate/933dfdb2-f58e-4249-a89d-3a67341fb870", "//pages//warranty", "//www", "/10280186", "/112794", "/11279482/", "/11279482/checkouts/0466034c305e67c0713000a423b50664", "/11279482/checkouts/1ae60c5f593ced8a7267df3806055c7b", "/11279482/checkouts/1ee1fdd33be38b43aedd50b3e38e32fc", "/11279482/checkouts/1f617c3d259dde4d9d1e6f85ad68b2f5", "/11279482/checkouts/236f5844fb3648d8561e32e430693f9a", "/11279482/checkouts/2ddc154a98e14d30728a5625c5e350dc", "/11279482/checkouts/2e7483893a944986fa6173f94457dc7b", "/11279482/checkouts/2f602a83394337b0a3f5151080454912", "/11279482/checkouts/308f556dfbe33dfa0059191d6a39ee0b", "/11279482/checkouts/40c1a26266d73d485f04ede090cb401b", "/11279482/checkouts/4cd2346081c3b1c9b1cc501a4184be38", "/11279482/checkouts/4d34f28e98618b4e1052f5edcb459493", "/11279482/checkouts/4f2934b3325b4d1e78fa724da9a03dba", "/11279482/checkouts/4ff538dee9d0ac10abb08f6b8ca6248d", "/11279482/checkouts/511e7cb6880e42edc6eae799c70c78f0", "/11279482/checkouts/58facace7acafada5c5cbe7c80d83188", "/11279482/checkouts/5e49128d6d55cafe4484b3f5cac745bd", "/11279482/checkouts/72a9ebd6377c905de07c4916cef19c05", "/11279482/checkouts/7538d74248dbf34b1cfe4857e3b64a7d", "/11279482/checkouts/7580e025cf26cf33ea3dbd6091b73314", "/11279482/checkouts/78b8180b4643656c9c5d270b9ad09073"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_utm_campaign",
+ "original_column_name": "event_utm_campaign",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "UTM campaign parameter for campaign-level attribution.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "15.710017654248338",
+ "column_distinct_count": "30",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["acquisition_campaign", "anniversary_sale", "back_to_school", "brand_awareness", "bundle_promotion", "clearance_event", "customer_appreciation", "email_blast", "end_of_season", "fall_promo", "flash_sale", "holiday_campaign", "limited_time_offer", "loyalty_program", "mega_sale", "member_exclusive", "new_arrivals", "newsletter_promotion", "product_launch", "referral_campaign", "remarketing_push", "retargeting_ads", "retention_initiative", "seasonal_promo", "social_media_promo", "spring_launch", "summer_sale_2024", "weekend_special", "win_back", "winter_deals"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Tracking platform emitting the event (elevar, blotout, snowplow, snowplow_ga4, heap, ga4).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["elevar"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_utm_source",
+ "original_column_name": "event_utm_source",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "UTM source parameter for attribution analysis (e.g., google, facebook, email).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(direct)", "google", "klaviyo", "meta", "tiktok"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_page_title",
+ "original_column_name": "event_page_title",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Page title where the event occurred for content analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "5.3564088550018294",
+ "column_distinct_count": "2853",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++lyeglaik", "++s7crzhbb", "+00zfwezup", "+01oojjq2e", "+07ulynhcd", "+0swuwky4a", "+0weahodjr", "+0x6ylbwce", "+1qm0uw1+m", "+1siylm676", "+1vnhjxuhn", "+294n9xxfu", "+2py6v0x8k", "+36bp6e2qn", "+3i5dswcy2", "+3szhszv9v", "+41jimei5o", "+47moo/9w5", "+4ist4zp+g", "+4jquel21k", "+4uytotvnk", "+4zdxxb9bd", "+5c8s/ow6d", "+5wh15uxm+", "+5wijxnuit", "+6+y3zchlt", "+62ikti4ok", "+6ihrx8xaa", "+6sfqa+afl", "+7iejo3u34"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_page_url",
+ "original_column_name": "event_page_url",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "Page URL without query parameters where the event occurred.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "36743",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(select(0)from(select(sleep(15)))v)/*\u0027+(select(0)from(select(sleep(15)))v)+\u0027\"+(select(0)from(select(sleep(15)))v)+\"*/uutrgqiy0n", "@@04vzrxny7brpmtl", "@@0n66dclwpik7/mc", "@@1dlhciowppl6rse", "@@2ffqavxwnjzjgi2", "@@52nic9/bf4s2tt9", "@@5l20gycrsr+irto", "@@6ut36yovwb1oqqj", "@@7htn77vnrmjvz1a", "@@7lx7nallzclmrxx", "@@9npihvogvixt4yg", "@@ag6s2wzqu4gj141", "@@apeaflprqg51edl", "@@asmwtoaxqkie0bs", "@@byprwjk5mw4natm", "@@cfdwzxeiqlp+tvw", "@@chhg9norrtviwli", "@@cl5oauir2dqspmk", "@@ctnck2qchrqwwxh", "@@dulrycchjyz3eyk", "@@e8anyrln4swsp0i", "@@eoy4wkgz1n5lyn9", "@@fotesqzlprrodmj", "@@fp0vb/17u68cscz", "@@gf9ovcwiqnldkwj", "@@gnkhtjdm0+jyx8r", "@@gsmpfqjjcu4rxmo", "@@gytz1upkmhy/0s9", "@@hpus9g5vz419zof", "@@i3wnobtcbddmvy2"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_utm_medium",
+ "original_column_name": "event_utm_medium",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "UTM medium parameter for channel grouping (e.g., cpc, social, email).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "5",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["(none)", "cpc", "email", "paid_social", "sms"]
+}, {
+ "table_name": "rpt_funnel_events_performance_hourly",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Hourly",
+ "primary_use_case": "Reporting",
+ "column_name": "event_utm_content",
+ "original_column_name": "event_utm_content",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Hourly funnel event aggregation for near-real-time conversion monitoring. Grain: One row per (hour x event dimension). Date field: event_local_datetime. Critical filters: event_local_datetime for hourly/daily time windows. Key joins: none; drill down to obt_funnel_event_history using event dimensions and time window filters. ",
+ "column_description": "UTM content parameter for A/B testing and ad variation tracking.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "30.363055751347943",
+ "column_distinct_count": "5636",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++0721yd8e", "++dktxnmpj", "++vuyjnqh2", "+/9iesbxsk", "+/hw2fnkr7", "+/rrm+r6uw", "+0ibrpd/d9", "+0ngvpf3/q", "+1n5s0mntm", "+1poviumbf", "+2mnsa/sap", "+2moz4tvn2", "+3itffxq9c", "+3os2ofaa8", "+3plxlabf9", "+4/h5g1k0f", "+4bkiprgvp", "+4rk9hmwjr", "+4rmqmwnpg", "+63bxygrdc", "+6bgigwtoa", "+6daxcwu/b", "+6hz/ijdjm", "+7jvdrkz2d", "+7wgdqy7h9", "+8k241u5hb", "+8qo0wyhuz", "+8ux+a2b4m", "+9ybjllw42", "+ar+6rxvnd"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "campaign_id",
+ "original_column_name": "campaign_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Messaging campaign identifier (if message_type is campaign).",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.4416295539169162",
+ "column_distinct_count": "2844",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++le+zun1c", "+/b51z5dug", "+/hz7mornb", "+0lmmm5mbc", "+1asfnvax/", "+2hrw/d7ms", "+64qm2rpcw", "+6vcdi5109", "+6vhfflfle", "+7fnj5w8pm", "+7rpagzzzz", "+ahr4jkxht", "+aiyl+vds0", "+b6mhhwpke", "+cl0gxg1vq", "+derzja9y3", "+djad4uzch", "+e0xniqxos", "+fk4+1rzn0", "+h2byudjuh", "+h6be8pd/6", "+hvcz8nbk8", "+hvmudonf7", "+isamqe2+8", "+iwqurrztp", "+j1ke4pmmq", "+jj3noofdz", "+jlljfxhk8", "+k+2i0tbkq", "+k73cc/u1r"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_subject",
+ "original_column_name": "message_subject",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "The subject line of the message (primarily for email campaigns). NULL for SMS/push messages that don\u0027t have subject lines. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "48.188697472226693",
+ "column_distinct_count": "541",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++s4wxsnzt", "+9poqwg8gt", "+ft0/qwv9q", "+hm9iny4u4", "+lumsw+adf", "+sabcbxnuz", "/9u8+kemzx", "/ced9csa2k", "/gsqvegg7a", "/ubiilopij", "/uetcyjwni", "/utkbdt+k7", "/wky46w4jp", "/wxioehelf", "0/0shwvkiw", "01r40rkk/x", "0g8x9qrxrr", "0hrrjlvac3", "0mg2wicdzp", "0mg9hnhdsj", "0pebe3b936", "0qli4npmwm", "0tmwzeoh2x", "0tt6dsnxm/", "12cos4bye9", "1fyu07rowt", "1nnlnoo7m6", "1smhko/nke", "1ubr8fdczt", "1wjxs9jfzw"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_name",
+ "original_column_name": "message_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "The name/title of the message as configured in the messaging platform. Used to identify specific email templates, SMS messages, or push notifications. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.6150029188558088",
+ "column_distinct_count": "3949",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++jrokxrk5", "+/hmdvvypy", "+/sexk8+bt", "+0k4yioohs", "+0t/x/efzw", "+1osabouom", "+2gcuids7p", "+396io0w3t", "+6j1ip22mp", "+6qo2qxwdw", "+7/w/ovw53", "+8lh6lamdz", "+8vqyy8ekf", "+a0rgwbin9", "+a4ktsh8n4", "+a9okt5wah", "+acjt5hb5h", "+ag6cm+yj4", "+ayv3m/m73", "+b+39ungb4", "+czyue4ve+", "+degeqa1kg", "+e3+wpqjio", "+fhysnv6ce", "+fv/dx12n9", "+hd43jxjhe", "+hw33db0l1", "+hwhwrcfnh", "+i/f2ms547", "+iunmdzdwi"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "source_system",
+ "original_column_name": "source_system",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "The messaging platform that sent the message (e.g., Klaviyo, Postscript, Attentive). Used to segment performance by messaging service provider. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["klaviyo"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "dimension_value",
+ "original_column_name": "dimension_value",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Dimension grouping value (e.g., campaign or flow identifier) depending on report mode.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "4221",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++le+zun1c", "+/40sc0vnq", "+/6bdps5gb", "+/b51z5dug", "+/hz7mornb", "+0lmmm5mbc", "+2hrw/d7ms", "+6+ta4d3rx", "+64qm2rpcw", "+6vcdi5109", "+6vhfflfle", "+7/w/ovw53", "+7fnj5w8pm", "+ahr4jkxht", "+aiyl+vds0", "+b6mhhwpke", "+bngrbjrbq", "+cl0gxg1vq", "+cqjpmvlv1", "+dczhbpdld", "+derzja9y3", "+djad4uzch", "+dktqx1opd", "+e0xniqxos", "+eyi53fr7j", "+fk4+1rzn0", "+gpu9ykwzs", "+gzv7stxqh", "+h2byudjuh", "+h6be8pd/6"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_message_channel",
+ "original_column_name": "sm_message_channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Normalized message channel (email, sms, push).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.5090807734060965",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["email"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "sm_store_id",
+ "original_column_name": "smcid",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "SourceMedium\u0027s unique store identifier. For Shopify stores, derived from the myshopify.com domain; for other platforms (Amazon, TikTok Shop, Walmart.com), uses platform-specific identifiers.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["ac5o7mxmrd"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "campaign_name",
+ "original_column_name": "campaign_name",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Messaging campaign name (if message_type is campaign).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.5887316476946416",
+ "column_distinct_count": "2830",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["[klaviyo][campaign]100558", "[klaviyo][campaign]100680", "[klaviyo][campaign]100824", "[klaviyo][campaign]100950", "[klaviyo][campaign]101302", "[klaviyo][campaign]101486", "[klaviyo][campaign]101545", "[klaviyo][campaign]101698", "[klaviyo][campaign]101850", "[klaviyo][campaign]102086", "[klaviyo][campaign]102092", "[klaviyo][campaign]102212", "[klaviyo][campaign]102510", "[klaviyo][campaign]103132", "[klaviyo][campaign]103281", "[klaviyo][campaign]103329", "[klaviyo][campaign]103744", "[klaviyo][campaign]103767", "[klaviyo][campaign]103993", "[klaviyo][campaign]104174", "[klaviyo][campaign]104260", "[klaviyo][campaign]104625", "[klaviyo][campaign]104685", "[klaviyo][campaign]104745", "[klaviyo][campaign]104908", "[klaviyo][campaign]105093", "[klaviyo][campaign]105404", "[klaviyo][campaign]105733", "[klaviyo][campaign]106165", "[klaviyo][campaign]106544"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "channel",
+ "original_column_name": "channel",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Sales channel for the message performance (always \u0027Online DTC\u0027 for email/SMS/push campaigns). Provides consistency with order-level channel attribution in multi-channel reporting. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "1",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_type",
+ "original_column_name": "message_type",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Whether the message originated from a flow/automation or from a campaign send.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.6135102246757485",
+ "column_distinct_count": "2",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["campaign", "flow"]
+}, {
+ "table_name": "rpt_outbound_message_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "message_id",
+ "original_column_name": "message_id",
+ "data_type": "STRING",
+ "is_nullable": "true",
+ "table_description": "Daily messaging performance across email/SMS/push for campaigns and flows. Grain: One row per (date x message/campaign context). Date field: date. Critical filters: sm_message_channel (email, sms, push); message_type (campaign vs flow). Key joins: none; drill down to message-detail models using (date, message context) filters. ",
+ "column_description": "Platform message identifier for the send.",
+ "is_key_column": "true",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-18",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "3.5418136908962596",
+ "column_distinct_count": "4094",
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": ["++le+zun1c", "+/40sc0vnq", "+/6bdps5gb", "+/b51z5dug", "+/hz7mornb", "+0lmmm5mbc", "+2hrw/d7ms", "+6+ta4d3rx", "+64qm2rpcw", "+6vcdi5109", "+6vhfflfle", "+7fnj5w8pm", "+ahr4jkxht", "+aiyl+vds0", "+b6mhhwpke", "+cl0gxg1vq", "+cqjpmvlv1", "+dczhbpdld", "+derzja9y3", "+djad4uzch", "+dktqx1opd", "+e0xniqxos", "+fk4+1rzn0", "+gpu9ykwzs", "+gzv7stxqh", "+h2byudjuh", "+h6be8pd/6", "+hsgs503tu", "+hvmudonf7", "+ijp/7mjeq"]
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ad_group_platform_metadata",
+ "original_column_name": "ad_group_platform_metadata",
+ "data_type": "STRUCT\u003cad_group_platform STRING, ad_group_id STRING, ad_group_name STRING, ad_campaign_id STRING, ad_campaign_name STRING, ad_campaign_tactic STRING, sm_ad_group_display_name STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing ad group platform metadata (ad_group_id, ad_group_name, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ad_platform_metadata",
+ "original_column_name": "ad_platform_metadata",
+ "data_type": "STRUCT\u003cad_platform STRING, ad_campaign_tactic STRING, ad_id STRING, ad_name STRING, sm_ad_display_name STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing ad platform metadata (ad_id, ad_name, platform details).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "campaign_platform_metadata",
+ "original_column_name": "campaign_platform_metadata",
+ "data_type": "STRUCT\u003ccampaign_platform STRING, ad_campaign_id STRING, ad_campaign_name STRING, ad_campaign_type STRING, ad_campaign_tactic STRING, sm_campaign_display_name STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing campaign platform metadata (campaign_id, campaign_name, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_conversion_windows",
+ "original_column_name": "ad_platform_reported_conversion_windows",
+ "data_type": "STRUCT\u003cdefault_window FLOAT64, _1d_click FLOAT64, _7d_click FLOAT64, _1d_view FLOAT64, _7d_view FLOAT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "Struct containing platform-reported conversion metrics across different attribution windows. Enables analysis of how attribution window selection affects reported performance. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "rpt_ad_performance_daily",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Report",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Marketing",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Reporting",
+ "column_name": "ad_platform_reported_revenue_windows",
+ "original_column_name": "ad_platform_reported_revenue_windows",
+ "data_type": "STRUCT\u003cdefault_window FLOAT64, _1d_click FLOAT64, _7d_click FLOAT64, _1d_view FLOAT64, _7d_view FLOAT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Daily advertising performance across platforms for spend, efficiency, and ROAS. Grain: One row per (smcid, source_system, sm_channel, date, ad_id). Date field: date. Critical filters: sm_channel for segmentation; source_system for platform analysis. Key joins: none; drill down to platform detail using (source_system, ad_id); blend with rpt_executive_summary_daily via (date, sm_channel). ",
+ "column_description": "Struct containing platform-reported revenue metrics across different attribution windows. Enables analysis of how attribution window selection affects reported revenue performance. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "attribution_metadata",
+ "original_column_name": "attribution_metadata",
+ "data_type": "STRUCT\u003cevent_utm_source STRING, event_utm_medium STRING, event_utm_campaign STRING, event_utm_content STRING, event_utm_term STRING, event_utm_id STRING, event_referrer_domain STRING, sm_event_page_category STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing UTM parameters and event metadata for attribution tracking.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "linear_conversion_impact",
+ "original_column_name": "linear_conversion_impact",
+ "data_type": "STRUCT\u003cmarketing_channel FLOAT64, ad FLOAT64, campaign FLOAT64, ad_group FLOAT64, landing_page FLOAT64, email_sms FLOAT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing conversion credit (fractional) attributed to this touchpoint using linear model for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "linear_revenue_impact",
+ "original_column_name": "linear_revenue_impact",
+ "data_type": "STRUCT\u003cmarketing_channel FLOAT64, landing_page FLOAT64, ad FLOAT64, campaign FLOAT64, ad_group FLOAT64, email_sms FLOAT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing revenue attributed to this touchpoint using linear attribution for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "days_to_conversion",
+ "original_column_name": "days_to_conversion",
+ "data_type": "STRUCT\u003cmarketing_channel INT64, ad INT64, campaign INT64, ad_group INT64, landing_page INT64, email_sms INT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing days between first touch and purchase conversion for each attribution dimension",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "last_touch_conversion_impact",
+ "original_column_name": "last_touch_conversion_impact",
+ "data_type": "STRUCT\u003cmarketing_channel INT64, landing_page INT64, ad INT64, campaign INT64, ad_group INT64, email_sms INT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing conversion (1 or 0) attributed to this touchpoint as last touch for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "first_touch_conversion_impact",
+ "original_column_name": "first_touch_conversion_impact",
+ "data_type": "STRUCT\u003cmarketing_channel INT64, landing_page INT64, ad INT64, campaign INT64, ad_group INT64, email_sms INT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing conversion (1 or 0) attributed to this touchpoint as first touch for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "first_touch_revenue_impact",
+ "original_column_name": "first_touch_revenue_impact",
+ "data_type": "STRUCT\u003cmarketing_channel NUMERIC, landing_page NUMERIC, ad NUMERIC, campaign NUMERIC, ad_group NUMERIC, email_sms NUMERIC\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing revenue attributed to this touchpoint if it was the first touch for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "last_touch_revenue_impact",
+ "original_column_name": "last_touch_revenue_impact",
+ "data_type": "STRUCT\u003cmarketing_channel NUMERIC, landing_page NUMERIC, ad NUMERIC, campaign NUMERIC, ad_group NUMERIC, email_sms NUMERIC\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing revenue attributed to this touchpoint if it was the last touch for each dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "last_touch_dimension_value",
+ "original_column_name": "last_touch_dimension_value",
+ "data_type": "STRUCT\u003cmarketing_channel STRING, ad STRING, campaign STRING, ad_group STRING, landing_page STRING, email_sms STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing the dimension values for the last valid touch in each attribution dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "dimension_value",
+ "original_column_name": "dimension_value",
+ "data_type": "STRUCT\u003cmarketing_channel STRING, ad STRING, campaign STRING, ad_group STRING, landing_page STRING, email_sms STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "The dimension value of the touch for the marketing channel. For example, a touchpoint with marketing channel of \"landing page\" will have the url path as the dimension value. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "first_touch_dimension_value",
+ "original_column_name": "first_touch_dimension_value",
+ "data_type": "STRUCT\u003cmarketing_channel STRING, ad STRING, campaign STRING, ad_group STRING, landing_page STRING, email_sms STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing the dimension values for the first valid touch in each attribution dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "is_valid_touch",
+ "original_column_name": "is_valid_touch",
+ "data_type": "STRUCT\u003cmarketing_channel_non_brand BOOL, marketing_channel_all BOOL, marketing_channel_last_touch BOOL, ad_id_non_brand BOOL, ad_id_all BOOL, ad_id_last_touch BOOL, campaign_id_non_brand BOOL, campaign_id_all BOOL, campaign_id_last_touch BOOL, ad_group_id_non_brand BOOL, ad_group_id_all BOOL, ad_group_id_last_touch BOOL, landing_page BOOL, email_sms BOOL\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct indicating whether touch is valid for each attribution dimension.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "sm_is_purchase_attributable_by",
+ "original_column_name": "sm_is_purchase_attributable_by",
+ "data_type": "STRUCT\u003cmarketing_channels BOOL, ads BOOL, campaigns BOOL, ad_groups BOOL, landing_pages BOOL, email_sms BOOL\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct indicating which dimensions this purchase can be attributed by based on business rules.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "unique_dimension_value_count",
+ "original_column_name": "unique_dimension_value_count",
+ "data_type": "STRUCT\u003cmarketing_channels INT64, ads INT64, campaigns INT64, ad_groups INT64, landing_pages INT64, email_sms INT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Count of distinct dimension values in the purchase journey.",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "valid_touch_count",
+ "original_column_name": "valid_touch_count",
+ "data_type": "STRUCT\u003cmarketing_channels INT64, ads INT64, campaigns INT64, ad_groups INT64, landing_pages INT64, email_sms INT64\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing count of valid touches for each dimension (marketing_channels, landing_pages, ads, campaigns, ad_groups, email_sms).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_purchase_journeys_with_mta_models",
+ "dataset_name": "sm_experimental",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_experimental",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "order_metadata",
+ "original_column_name": "order_metadata",
+ "data_type": "STRUCT\u003corder_discount_codes_csv STRING, sm_order_type STRING, order_sequence STRING, subscription_order_sequence STRING, sm_zero_party_attribution_source STRING, sm_utm_source STRING, sm_utm_medium STRING, sm_utm_campaign STRING, sm_utm_content STRING, sm_utm_term STRING, sm_utm_id STRING\u003e",
+ "is_nullable": "true",
+ "table_description": "Multi-Touch Attribution (MTA) model for purchase journeys with revenue impact calculations. Includes first touch, last touch, and linear attribution models across multiple dimensions. ",
+ "column_description": "Struct containing order metadata fields (order_id, customer details, etc.).",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": null,
+ "column_distinct_count": null,
+ "column_sample_min": null,
+ "column_sample_max": null,
+ "stats_computed_at": null,
+ "stats_sample_percent": null,
+ "stats_method": null,
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customer_addresses",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer address dimension for enriching customers and orders with normalized geo attributes. Grain: One row per sm_customer_address_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform coverage and address availability; is_default_for_customer for primary address. Key joins: dim_customers via sm_customer_key (many:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "12925",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-18 23:59:51.052+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_created_at",
+ "original_column_name": "customer_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "UTC timestamp when the customer was created.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.2067708790726268",
+ "column_distinct_count": "78769",
+ "column_sample_min": "2016-04-01 08:42:15+00",
+ "column_sample_max": "2025-10-18 16:46:26+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "customer_updated_at",
+ "original_column_name": "customer_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "UTC timestamp when the customer was last modified.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.28266787158774",
+ "column_distinct_count": "78708",
+ "column_sample_min": "2016-05-22 01:56:21+00",
+ "column_sample_max": "2025-10-18 16:35:41+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer dimension with stable keys and profile attributes for joining and segmentation. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific coverage differences. Key joins: dim_orders via sm_customer_key (1:many). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "3059",
+ "column_sample_min": "2025-10-18 00:39:08.517+00",
+ "column_sample_max": "2025-10-19 17:33:09.320+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_discounts",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order discount dimension with discount types, codes, and values. Grain: One row per sm_order_discount_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific discount representation. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "9496",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-18 23:58:20.090+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_shipping_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order shipping line dimension for shipping method and cost details at line-level. Grain: One row per sm_shipping_line_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific shipping representation. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (many:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "9100",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-18 23:59:56+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_order_taxes",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order tax dimension with tax names and amounts for reconciliation and reporting. Grain: One row per sm_order_tax_key. No canonical date; _synced_at is a freshness timestamp (not for analysis). Critical filters: source_system for platform-specific tax reporting, tax_line_entity for line vs shipping taxes. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "18663",
+ "column_sample_min": "2025-10-18 00:00:00+00",
+ "column_sample_max": "2025-10-18 23:59:51.358+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_processed_at",
+ "original_column_name": "order_processed_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "UTC timestamp when the order was processed.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64716",
+ "column_sample_min": "2016-04-13 21:49:48+00",
+ "column_sample_max": "2025-10-18 13:56:52+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_updated_at",
+ "original_column_name": "order_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "UTC timestamp from source system when the order was last modified. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "52357",
+ "column_sample_min": "2017-02-14 23:22:45+00",
+ "column_sample_max": "2025-10-18 17:46:35+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_created_at",
+ "original_column_name": "order_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "UTC timestamp when the order was created.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "64344",
+ "column_sample_min": "2016-01-20 20:08:53+00",
+ "column_sample_max": "2025-10-18 14:53:55+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "order_cancelled_at",
+ "original_column_name": "order_cancelled_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order dimension with stable keys and descriptive attributes for joining and exploration. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: sm_channel for channel segmentation; source_system for platform-specific behavior. Platform caveat: TikTok Shop coverage may be limited. Key joins: dim_order_lines via sm_order_key (1:many); dim_customers via sm_customer_key (many:1). ",
+ "column_description": "UTC timestamp when the order was cancelled. Null if order has not been cancelled.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "91.068255219198619",
+ "column_distinct_count": "5768",
+ "column_sample_min": "2017-01-03 20:39:00+00",
+ "column_sample_max": "2025-10-17 09:50:48+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_updated_at",
+ "original_column_name": "product_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The date and time when the product was last modified. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28",
+ "column_sample_min": "2025-03-31 21:42:16+00",
+ "column_sample_max": "2025-10-18 10:11:09+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_created_at",
+ "original_column_name": "product_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The date and time when the product was created. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "2.083333333333333",
+ "column_distinct_count": "44",
+ "column_sample_min": "2017-06-13 16:32:21+00",
+ "column_sample_max": "2025-09-12 16:50:20+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_updated_at",
+ "original_column_name": "product_variant_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The date and time when the product variant was last modified. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "32",
+ "column_sample_min": "2017-07-01 02:26:37+00",
+ "column_sample_max": "2025-10-18 10:11:09+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "dim_product_variants",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Dimension",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Products",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Dimensional Analysis",
+ "column_name": "product_variant_created_at",
+ "original_column_name": "product_variant_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Product variant dimension for enriching line items with stable keys and attributes. Grain: One row per sm_product_variant_key. Date field: product_variant_created_at. Critical filters: source_system for platform-specific variant coverage and naming. Key joins: dim_order_lines via sm_product_variant_key (1:many). ",
+ "column_description": "The date and time when the product variant was created. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "false",
+ "table_last_data_date": "2025-09-23",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "45",
+ "column_sample_min": "2016-09-08 02:31:41+00",
+ "column_sample_max": "2025-08-13 15:35:27+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_orders_placed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Placed order fact table for order-count analytics and funnel tie-ins. Grain: One row per sm_order_line_key. Date field: order_created_at_local_datetime. Critical filters: source_system for platform-specific order placement reporting; order_created_at_local_datetime for temporal analysis. Key joins: dim_orders via sm_order_key (many:1); dim_order_lines via sm_order_line_key (1:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "9349",
+ "column_sample_min": "2025-10-17 22:40:12.791+00",
+ "column_sample_max": "2025-10-19 18:07:13.416+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "refunded_at",
+ "original_column_name": "refunded_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "The autogenerated date and time when the refund was processed. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "11905",
+ "column_sample_min": "2016-07-02 00:47:13+00",
+ "column_sample_max": "2025-10-18 09:31:38+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "fct_refunds_processed",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "Fact",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Refunds",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Fact Analysis",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Refund transaction fact table for revenue adjustments and return analytics. Grain: One row per sm_refund_line_key. Date field: refunded_at_local_datetime. Critical filters: source_system for platform-specific refund reporting; refunded_at_local_datetime for temporal analysis. Key joins: dim_order_lines via sm_order_line_key (many:1); dim_orders via sm_order_key (many:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "489",
+ "column_sample_min": "2025-04-27 00:00:00+00",
+ "column_sample_max": "2025-10-19 14:02:49.786+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_updated_at",
+ "original_column_name": "ticket_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "UTC timestamp when the ticket was last updated/modified. Tracks any changes to ticket status, assignee, or new messages. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "23872",
+ "column_sample_min": "2020-12-31 04:38:59.912+00",
+ "column_sample_max": "2025-10-18 06:17:12.719515+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_last_message_at",
+ "original_column_name": "ticket_last_message_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "UTC timestamp of the last message sent or received in the ticket conversation. Used to track ticket activity and identify stale tickets. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.10135961693055119",
+ "column_distinct_count": "28693",
+ "column_sample_min": "2019-09-28 02:14:43.957+00",
+ "column_sample_max": "2025-10-18 04:51:07.898596+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "169",
+ "column_sample_min": "2025-10-18 00:17:02.839+00",
+ "column_sample_max": "2025-10-19 17:44:56.954+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_closed_at",
+ "original_column_name": "ticket_closed_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "UTC timestamp when the ticket was closed/resolved. NULL for open tickets; used with ticket_created_at to calculate resolution time. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "7.5875620518477653",
+ "column_distinct_count": "26928",
+ "column_sample_min": "2019-09-14 18:15:17.531+00",
+ "column_sample_max": "2025-10-18 06:08:16.916562+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customer_support_tickets",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "ticket_created_at",
+ "original_column_name": "ticket_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer support ticket analytics for lifecycle, agent performance, and channel analysis. Grain: One row per sm_ticket_key. Date field: ticket_created_at_local_datetime. Critical filters: sm_channel for ticket context; ticket_communication_channel for platform segmentation (email, instagram-direct-message, etc.). Key joins: dim_customers via customer_id (platform-dependent; primarily Shopify). ",
+ "column_description": "Timestamp when the ticket was created (UTC)",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "28388",
+ "column_sample_min": "2018-09-07 03:32:11+00",
+ "column_sample_max": "2025-10-18 06:06:03+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "subscriber_created_at",
+ "original_column_name": "subscriber_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "The autogenerated date and time when the subscriber was created. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": "2025-10-18 00:46:31+00",
+ "column_sample_max": "2025-10-18 21:24:30+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "2922",
+ "column_sample_min": "2025-10-18 00:12:20.738+00",
+ "column_sample_max": "2025-10-19 18:00:27.738+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_created_at",
+ "original_column_name": "customer_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "UTC timestamp when the customer was created.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.0827883586797089",
+ "column_distinct_count": "79003",
+ "column_sample_min": "2016-04-05 10:45:47+00",
+ "column_sample_max": "2025-10-18 16:39:12+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_customers",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Customers",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "customer_updated_at",
+ "original_column_name": "customer_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Customer analytics table for acquisition, subscription status, and cohort analysis. Grain: One row per sm_customer_key. Date field: customer_created_at. Critical filters: source_system for platform-specific analysis. Key joins: obt_orders via sm_customer_key (1:many); dim_customers via sm_customer_key (1:1). ",
+ "column_description": "UTC timestamp when the customer was last modified.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "9.2435951373973122",
+ "column_distinct_count": "78747",
+ "column_sample_min": "2016-05-03 01:21:14+00",
+ "column_sample_max": "2025-10-18 16:56:19+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "_synced_at",
+ "original_column_name": "_synced_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "UTC timestamp when SourceMedium last synced the row. Freshness indicator only; not for time-series analysis.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "52132",
+ "column_sample_min": "2025-10-18 04:00:14.489+00",
+ "column_sample_max": "2025-10-19 15:59:41.759+00",
+ "stats_computed_at": "2025-10-19 22:15:26.247419 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "SAMPLE_10_LAST_60D",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_funnel_event_history",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Other",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "General",
+ "column_name": "event_time",
+ "original_column_name": "event_time",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Unified funnel event history across tracking sources (Elevar, Blotout, Snowplow/GA4, Heap) for pathing and attribution. Grain: One row per event (sm_event_key). Date field: event_local_datetime. Critical filters: source_system (tracking platform); sm_event_name (event type: purchase, add_to_cart, etc.). Key joins: obt_orders via event_order_id \u003d order_id (many:1) when available. ",
+ "column_description": "Raw event timestamp from the source tracking platform (may be in various formats). Use event_local_datetime for standardized time-series analysis. ",
+ "is_key_column": "false",
+ "is_temporal_column": "false",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "100.0",
+ "column_distinct_count": "0",
+ "column_sample_min": "2025-10-18 07:01:51.029+00",
+ "column_sample_max": "2025-10-19 06:59:57.274+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_order_lines",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_processed_at",
+ "original_column_name": "order_processed_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Product-level analytics table for order line revenue, costs, and profitability. Grain: One row per sm_order_line_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Key joins: obt_orders via sm_order_key (many:1); dim_product_variants via sm_product_variant_key (many:1). ",
+ "column_description": "UTC timestamp from source system when the order was processed. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0024125840383440022",
+ "column_distinct_count": "115813",
+ "column_sample_min": "2016-01-28 18:43:55+00",
+ "column_sample_max": "2025-10-18 17:11:16+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_cancelled_at",
+ "original_column_name": "order_cancelled_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "UTC timestamp when the order was cancelled. Null if order has not been cancelled.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "93.126658880985246",
+ "column_distinct_count": "3238",
+ "column_sample_min": "2016-07-02 00:47:14+00",
+ "column_sample_max": "2025-10-17 23:11:10+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_processed_at",
+ "original_column_name": "order_processed_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "UTC timestamp when the order was processed.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "46959",
+ "column_sample_min": "2016-07-08 23:38:01+00",
+ "column_sample_max": "2025-10-18 17:46:19+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_created_at",
+ "original_column_name": "order_created_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "UTC timestamp when the order was created.",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "47488",
+ "column_sample_min": "2016-04-19 21:09:50+00",
+ "column_sample_max": "2025-10-18 17:11:20+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}, {
+ "table_name": "obt_orders",
+ "dataset_name": "sm_transformed_v2",
+ "table_type": "One Big Table",
+ "dataset_location": "sm_transformed_v2",
+ "business_domain": "Orders",
+ "refresh_frequency": "Daily",
+ "primary_use_case": "Analytics \u0026 BI",
+ "column_name": "order_updated_at",
+ "original_column_name": "order_updated_at",
+ "data_type": "TIMESTAMP",
+ "is_nullable": "true",
+ "table_description": "Order analytics table for revenue, profitability, refunds, and channel performance analysis. Grain: One row per sm_order_key. Date field: order_processed_at_local_datetime. Critical filters: is_order_sm_valid \u003d TRUE (exclude test/cancelled orders); sm_channel for segmentation. Platform caveat: TikTok Shop coverage may be limited. Key joins: obt_order_lines via sm_order_key (1:many); obt_customers via sm_customer_key (many:1); dim_orders via sm_order_key (1:1). ",
+ "column_description": "UTC timestamp from source system when the order was last updated. ",
+ "is_key_column": "false",
+ "is_temporal_column": "true",
+ "is_numeric_column": "false",
+ "table_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "column_description_updated_at": "2025-10-19 18:32:01.120308 UTC",
+ "_synced_at": "2025-10-19 22:20:59.811929 UTC",
+ "table_has_data": "true",
+ "table_has_fresh_data_14d": "true",
+ "table_last_data_date": "2025-10-19",
+ "sm_store_id": "irestore-4",
+ "column_null_percentage": "0.0",
+ "column_distinct_count": "39123",
+ "column_sample_min": "2017-02-21 01:45:58+00",
+ "column_sample_max": "2025-10-18 17:45:28+00",
+ "stats_computed_at": "2025-10-20 00:47:09.882382 UTC",
+ "stats_sample_percent": "10.0",
+ "stats_method": "DEMO_SAMPLE_10_RECOMPUTED",
+ "categorical_values_array": []
+}]
\ No newline at end of file
diff --git a/yaml-files/rpt_ad_performance_daily.yml b/yaml-files/rpt_ad_performance_daily.yml
index 3031159..50ebc29 100644
--- a/yaml-files/rpt_ad_performance_daily.yml
+++ b/yaml-files/rpt_ad_performance_daily.yml
@@ -10,17 +10,17 @@ models:
columns:
- name: sm_master_account_id
description: >
- The unique identifier for the master account that is associated with the SourceMedium smcid.
+ The unique identifier for the master account that is associated with the SourceMedium sm_store_id.
- name: sm_parent_company_name
description: >
- The name of the parent company that is associated with the SourceMedium smcid.
+ The name of the parent company that is associated with the SourceMedium sm_store_id.
- name: sm_store_name
description: >
- The name of the store that is associated with the SourceMedium smcid.
+ The name of the store that is associated with the SourceMedium sm_store_id.
- - name: smcid
+ - name: sm_store_id
description: >
The SourceMedium ID of a store, which is derived from the store's myshopify.com domain.
tests: