Skip to content

Data Product Block

The data_product block defines curated analytics outputs for specific consumers and use cases. Data products represent the final layer of your data architecture - the reports, dashboards, and metrics that business users consume.

Purpose

Data products help you document and manage:

  • What reports and dashboards are available
  • Which metrics and KPIs are tracked
  • Who consumes the data and for what purpose
  • Who owns and maintains each product
  • How often data is refreshed

Syntax

mml
data_product "ProductName" {
  description = "Product description"
  owner = "team-name"
  refresh_schedule = "0 0 * * *"  # Cron expression

  # Consumers
  consumer "team-name"
  consumer "dashboard-url"

  # Reports within this product
  report "ReportName" { ... }
}

Attributes

Optional Attributes

description

A clear description of what the data product provides and its intended use cases.

  • Type: String
  • Required: No (but highly recommended)
mml
data_product "Customer Analytics" {
  description = "Customer behavior and lifecycle analytics"
}

owner

The team or individual responsible for maintaining the data product.

  • Type: String
  • Required: No (but highly recommended)
mml
data_product "Customer Analytics" {
  owner = "analytics-team"
}

refresh_schedule

The schedule for refreshing the product data using cron expression format.

  • Type: String
  • Required: No
  • Format: Cron expression (e.g., "0 6 * * *" for daily at 6am)
mml
data_product "Customer Analytics" {
  refresh_schedule = "0 6 * * *"  # Daily at 6am
}

Consumer Declarations

The consumer keyword declares who uses this data product.

Syntax:

mml
consumer "team-name"
consumer "dashboard-url"

Example:

mml
data_product "Customer Analytics" {
  consumer "product-team"
  consumer "executives"
  consumer "https://analytics.company.com/customer-dashboard"
}

Reports

Data products contain reports that group related metrics and visualizations together. See the Report documentation for details on defining reports within data products.

Example:

mml
data_product "Sales Analytics" {
  description = "Sales performance metrics"
  owner = "sales-team"

  report "Revenue Dashboard" {
    type = "dashboard"
    uses "Sales.Order"
    uses "Sales.Customer"

    metric "Total Revenue" {
      description = "Sum of all orders"
      calculation = "SUM(Order.amount)"
      uses "Sales.Order"
    }
  }
}

Examples

Basic Data Product

mml
data_product "Customer Analytics" {
  description = "Customer behavior and lifecycle analytics"
  owner = "analytics-team"
  refresh_schedule = "0 6 * * *"  # Daily at 6am

  consumer "product-team"
  consumer "executives"
}

Data Product with Reports

mml
data_product "Sales Analytics" {
  description = "Sales performance metrics and dashboards"
  owner = "sales-team"
  refresh_schedule = "0 * * * *"  # Hourly

  consumer "sales-team"
  consumer "executives"

  report "Revenue Dashboard" {
    description = "Daily revenue and sales metrics"
    type = "dashboard"

    uses "Sales.Order"
    uses "Sales.Customer"

    metric "Total Revenue" {
      description = "Sum of all order values"
      calculation = "SUM(Order.amount)"
      target_value = "$1M monthly"
      uses "Sales.Order"
    }

    metric "Average Order Value" {
      description = "Average revenue per order"
      calculation = "AVG(Order.amount)"
      target_value = "$150"
      uses "Sales.Order"
    }
  }

  report "Customer Overview" {
    type = "dashboard"
    uses "Sales.Customer"

    metric "Customer Lifetime Value" {
      description = "Average revenue per customer over their lifetime"
      calculation = "SUM(Order.amount) / COUNT(DISTINCT Customer.id)"
      target_value = "$500"
      uses "Sales.Customer"
      uses "Sales.Order"
    }
  }
}

Complete Example

mml
# Define the domain and entities
domain "Sales" {
  color = "#e74c3c"
  description = "Customer sales and orders"

  entity "Customer" {
    type = "entity"
    description = "A customer who can place orders"
    pii = true

    attribute "email" {
      type = "string"
      required = true
      pii = true
    }

    attribute "lifetime_value" {
      type = "number"
      description = "Total revenue from this customer"
    }

    has-many "Sales.Order"
  }

  entity "Order" {
    type = "entity"
    description = "A customer order"

    attribute "amount" {
      type = "number"
      required = true
    }

    attribute "placed_at" {
      type = "date"
      required = true
    }

    belongs-to "Sales.Customer"
  }
}

# Define the data product
data_product "Sales Analytics" {
  description = "Sales performance metrics"
  owner = "sales-team"
  refresh_schedule = "0 * * * *"  # Hourly

  consumer "sales-team"
  consumer "executives"
  consumer "https://analytics.company.com/sales"

  report "Revenue Dashboard" {
    type = "dashboard"
    description = "Real-time revenue tracking"

    uses "Sales.Order"
    uses "Sales.Customer"

    metric "Total Revenue" {
      description = "Sum of all orders"
      calculation = "SUM(Order.amount)"
      target_value = "$1M monthly"
      uses "Sales.Order"
    }

    metric "Average Order Value" {
      description = "Average order amount"
      calculation = "AVG(Order.amount)"
      target_value = "$150"
      uses "Sales.Order"
    }

    metric "Customer Count" {
      description = "Number of unique customers"
      calculation = "COUNT(DISTINCT Customer.id)"
      target_value = "10,000 active customers"
      uses "Sales.Customer"
    }
  }

  report "Customer Insights" {
    type = "dashboard"
    description = "Customer behavior analysis"

    uses "Sales.Customer"
    uses "Sales.Order"

    metric "Customer Lifetime Value" {
      description = "Average revenue per customer"
      calculation = "SUM(Order.amount) / COUNT(DISTINCT Customer.id)"
      target_value = "$500"
      uses "Sales.Customer"
      uses "Sales.Order"
    }

    metric "Repeat Customer Rate" {
      description = "Percentage of customers with multiple orders"
      calculation = "COUNT(DISTINCT Customer WHERE order_count > 1) / COUNT(DISTINCT Customer) * 100"
      target_value = "40%"
      uses "Sales.Customer"
      uses "Sales.Order"
    }
  }
}

Best Practices

  1. Organize by consumer: Create data products around who will use them

    mml
    data_product "Executive Dashboard" {
      description = "C-suite metrics"
      consumer "executives"
    }
    
    data_product "Sales Team Analytics" {
      description = "Daily sales operations"
      consumer "sales-team"
    }
  2. Document ownership clearly: Always specify who maintains the product

    mml
    data_product "Customer Analytics" {
      owner = "analytics-team"
    }
  3. Set refresh schedules: Define how often data should be updated

    mml
    data_product "Real-time Dashboard" {
      refresh_schedule = "0 * * * *"  # Hourly
    }
    
    data_product "Daily Reports" {
      refresh_schedule = "0 6 * * *"  # Daily at 6am
    }
  4. List all consumers: Track who depends on this data

    mml
    data_product "Customer Analytics" {
      consumer "product-team"
      consumer "marketing-team"
      consumer "executives"
    }
  5. Group related reports: Keep related metrics together in the same product

    mml
    data_product "Sales Analytics" {
      report "Revenue Dashboard" { ... }
      report "Customer Insights" { ... }
      report "Product Performance" { ... }
    }
  6. Use clear names: Choose descriptive names that indicate purpose

    mml
    // Good
    data_product "Customer Lifecycle Analytics"
    
    // Avoid
    data_product "Dashboard 1"

Released under the MIT License.