agnes-the-ai-analyst/docs/metrics/marketing/cost_per_acquisition.yml
Petr 5a84473213 Add dynamic Business Metrics with sample e-commerce definitions
Replace hardcoded Keboola-specific metrics card in Data Catalog with
dynamic Jinja template that renders whatever metric YAMLs exist in
docs/metrics/. Add 10 sample e-commerce metric definitions across
4 categories (revenue, customers, marketing, support) that align
with the sample data generator tables.

Key changes:
- MetricParser: new category colors + dynamic sql_* field discovery
- _load_metrics_data(): scans docs/metrics/*/*.yml with prod fallback
- catalog.html: 240 lines hardcoded HTML -> 35 lines Jinja loop
- metric_modal.js: regex-based category class removal, new categories
- 21 tests validating YAML schema, parser, and loader
2026-03-10 22:38:44 +01:00

53 lines
1.7 KiB
YAML

- name: cost_per_acquisition
display_name: Cost per Acquisition
category: marketing
type: ratio
unit: USD
grain: monthly
time_column: start_date
table: campaigns
tables:
- campaigns
- customers
expression: "SUM(spend) / NULLIF(COUNT(DISTINCT new_customer_id), 0)"
description: "Average cost to acquire one new customer through marketing campaigns. Compares total campaign spend to the number of new customer registrations attributed to those campaigns."
dimensions:
- campaign_type
- channel
- region
notes:
- "Only counts first-time customers (no repeat purchasers)"
- "Joins campaigns to customers via attribution tracking"
- "CPA below customer lifetime value indicates sustainable growth"
synonyms:
- cpa
- customer_acquisition_cost
- cac
sql: |
SELECT
DATE_TRUNC('month', c.start_date) AS month,
SUM(c.spend) AS total_spend,
COUNT(DISTINCT cust.customer_id) AS new_customers,
ROUND(
SUM(c.spend) / NULLIF(COUNT(DISTINCT cust.customer_id), 0), 2
) AS cost_per_acquisition
FROM campaigns c
LEFT JOIN customers cust
ON cust.attribution_campaign = c.campaign_id
AND cust.is_first_purchase = true
GROUP BY 1
ORDER BY 1
sql_by_channel: |
SELECT
c.channel,
SUM(c.spend) AS total_spend,
COUNT(DISTINCT cust.customer_id) AS new_customers,
ROUND(
SUM(c.spend) / NULLIF(COUNT(DISTINCT cust.customer_id), 0), 2
) AS cpa
FROM campaigns c
LEFT JOIN customers cust
ON cust.attribution_campaign = c.campaign_id
AND cust.is_first_purchase = true
GROUP BY 1
ORDER BY 4