version: 1.0.0
info:
  title: Customer Onboarding
  version: 1.0.0

dataset: silver_crm_customers

links:
  - name: dim_geography
    path: ./data/dim_geography.csv
    type: csv
  - name: marketing_opt_outs
    path: ./data/marketing_opt_outs.csv
    type: csv

schema_policy:
  evolution: strict
  unknown_fields: drop

model:
  fields:
    - name: customer_id
      type: int
      required: true
    - name: email
      type: string
      required: true
    - name: first_name
      type: string
    - name: last_name
      type: string
    - name: birth_date
      type: date
    - name: membership_level
      type: string
    - name: country_id
      type: int
    - name: created_at
      type: date
    - name: region
      type: string
    - name: opted_out
      type: string
    - name: full_name
      type: string

transformations:
  - rename:
      mappings:
        email_address: email
    phase: pre
  - filter:
      sql: "email IS NOT NULL"
    phase: pre
  - deduplicate:
      on: ["email"]
      sort_by: ["created_at"]
      order: "desc"
    phase: pre
  - sql: |
      SELECT
        src.customer_id,
        src.email,
        src.first_name,
        src.last_name,
        src.birth_date,
        src.membership_level,
        src.country_id,
        src.created_at,
        COALESCE(geo.region, 'Unknown') AS region,
        COALESCE(opt.opted_out, 'false') AS opted_out,
        src.first_name || ' ' || src.last_name AS full_name
      FROM source src
      LEFT JOIN dim_geography geo ON src.country_id = geo.country_id
      LEFT JOIN marketing_opt_outs opt ON src.email = opt.email
    phase: post

quality:
  row_rules:
    - name: email_format
      sql: "email LIKE '%@%'"
      category: correctness
    - name: valid_membership
      sql: "membership_level IN ('GOLD','SILVER','BRONZE','PLATINUM')"
      category: consistency
    - name: valid_rejoin
      sql: "region IN ('USA','UK')"

lineage:
  enabled: true
  capture_source_path: true
  capture_timestamp: true
  capture_run_id: true

quarantine:
  include_error_reason: true
