From 9be6ec1dae17c21c800d46323f80fe1e470dc9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Roqu=C3=A9=20Paniagua?= Date: Thu, 24 Apr 2025 15:01:04 +0000 Subject: [PATCH] Merged PR 5055: KPIs models for API Billable Verifications # Description Changes: * 4 new models in the scope of KPIs for Billable Verifications from APIs. I believe it's more correct to say these are Billable Verifications than Billable Bookings since there's some cases in which a Booking can be duplicated and it's billed multiple times. These include: * A daily metric model - extremely simple. You will notice there's no Billing Country not Listing Segmentation. This is because for ALL API cases this is UNSET, thus, I just remove it. * An equivalent monthly metric model. * Two aggregated models per dimension, dimension value: on a daily and a monthly basis. Important change: the macro that handles the aggregations sets by default Billing Country and Listing Segmentation. I modified a bit the flow so the only required dimension is Global, and these are skipped for APIs models. This is needed for the changes intended on the Growth score. In there, I'll combine both Platform Billable Bookings with API Billable Verifications. Notice there's no MTD models. These could be added for sure; but since I'm not creating any metric in Main KPIs or similar, I opted to skip it for now. It can be done later on. # Checklist - [X] The edited models and dependants run properly with production data. - [X] The edited models are sufficiently documented. - [X] The edited models contain PK tests, and I've ran and passed them. - [X] I have checked for DRY opportunities with other models and docs. - [X] I've picked the right materialization for the affected models. # Other - [ ] Check if a full-refresh is required after this PR is merged. Related work items: #29374 --- macros/business_kpis_configuration.sql | 26 +- ...__agg_daily_api_billable_verifications.sql | 19 ++ ...agg_monthly_api_billable_verifications.sql | 24 ++ ...etric_daily_api_billable_verifications.sql | 14 ++ ...ric_monthly_api_billable_verifications.sql | 27 ++ models/intermediate/kpis/schema.yml | 230 ++++++++++++++++++ 6 files changed, 337 insertions(+), 3 deletions(-) create mode 100644 models/intermediate/kpis/int_kpis__agg_daily_api_billable_verifications.sql create mode 100644 models/intermediate/kpis/int_kpis__agg_monthly_api_billable_verifications.sql create mode 100644 models/intermediate/kpis/int_kpis__metric_daily_api_billable_verifications.sql create mode 100644 models/intermediate/kpis/int_kpis__metric_monthly_api_billable_verifications.sql diff --git a/macros/business_kpis_configuration.sql b/macros/business_kpis_configuration.sql index bbaeca4..14637cd 100644 --- a/macros/business_kpis_configuration.sql +++ b/macros/business_kpis_configuration.sql @@ -126,13 +126,21 @@ Provides a general assignement for the Dimensions available for each KPI {# Base dimensions shared by all models #} {% set base_dimensions = [ dim_global(), - dim_number_of_listings(), - dim_billing_country(), ] %} {# Initialize a list to hold any model-specific dimensions #} {% set additional_dimensions = [] %} + {# Adds Number of Listings and Billing Country dimension to all models except API models #} + {% if entity_name not in [ + "API_BILLABLE_VERIFICATIONS", + ] %} + {% set additional_dimensions = additional_dimensions + [ + dim_number_of_listings(), + dim_billing_country, + ] %} + {% endif %} + {# Adds Deal dimension to all models except DEAL metrics #} {% if entity_name not in [ "DEALS", @@ -142,7 +150,7 @@ Provides a general assignement for the Dimensions available for each KPI {% set additional_dimensions = additional_dimensions + [dim_deal()] %} {% endif %} - {# Add entity-specific dimensions #} + {# Add entity-specific dimensions - General - Business Scope #} {% if entity_name in [ "MAIN_KPIS_DATES", "BILLABLE_BOOKINGS", @@ -162,6 +170,7 @@ Provides a general assignement for the Dimensions available for each KPI {% set additional_dimensions = additional_dimensions + [dim_business_scope()] %} {% endif %} + {# Add entity-specific dimensions - Guests #} {% if entity_name == "CHECK_IN_ATTRIBUTED_GUEST_JOURNEYS" %} {% set additional_dimensions = additional_dimensions + [ dim_has_payment(), @@ -175,6 +184,17 @@ Provides a general assignement for the Dimensions available for each KPI ] %} {% endif %} + {# Add entity-specific dimensions - APIs #} + {% if entity_name in [ + "API_BILLABLE_VERIFICATIONS", + ] %} + {% set additional_dimensions = additional_dimensions + [ + dim_business_scope(), + dim_pricing_service(), + ] %} + {% endif %} + + {# Add entity-specific dimensions - New Dash #} {% if entity_name in [ "NEW_DASH_CREATED_SERVICES", "NEW_DASH_CHARGEABLE_SERVICES", diff --git a/models/intermediate/kpis/int_kpis__agg_daily_api_billable_verifications.sql b/models/intermediate/kpis/int_kpis__agg_daily_api_billable_verifications.sql new file mode 100644 index 0000000..3e0aff4 --- /dev/null +++ b/models/intermediate/kpis/int_kpis__agg_daily_api_billable_verifications.sql @@ -0,0 +1,19 @@ +{% set dimensions = get_kpi_dimensions_per_model("API_BILLABLE_VERIFICATIONS") %} + +{{ config(materialized="table", unique_key=["date", "dimension", "dimension_value"]) }} + + +{% for dimension in dimensions %} + select + -- Unique Key -- + date, + {{ dimension.dimension }} as dimension, + {{ dimension.dimension_value }} as dimension_value, + -- Metrics -- + sum(billable_verifications) as billable_verifications + from {{ ref("int_kpis__metric_daily_api_billable_verifications") }} + group by 1, 2, 3 + {% if not loop.last %} + union all + {% endif %} +{% endfor %} diff --git a/models/intermediate/kpis/int_kpis__agg_monthly_api_billable_verifications.sql b/models/intermediate/kpis/int_kpis__agg_monthly_api_billable_verifications.sql new file mode 100644 index 0000000..c03b301 --- /dev/null +++ b/models/intermediate/kpis/int_kpis__agg_monthly_api_billable_verifications.sql @@ -0,0 +1,24 @@ +{% set dimensions = get_kpi_dimensions_per_model("API_BILLABLE_VERIFICATIONS") %} + +{{ + config( + materialized="table", unique_key=["end_date", "dimension", "dimension_value"] + ) +}} + + +{% for dimension in dimensions %} + select + -- Unique Key -- + start_date, + end_date, + {{ dimension.dimension }} as dimension, + {{ dimension.dimension_value }} as dimension_value, + -- Metrics -- + sum(billable_verifications) as billable_verifications + from {{ ref("int_kpis__metric_monthly_api_billable_verifications") }} + group by 1, 2, 3, 4 + {% if not loop.last %} + union all + {% endif %} +{% endfor %} diff --git a/models/intermediate/kpis/int_kpis__metric_daily_api_billable_verifications.sql b/models/intermediate/kpis/int_kpis__metric_daily_api_billable_verifications.sql new file mode 100644 index 0000000..4cc5c97 --- /dev/null +++ b/models/intermediate/kpis/int_kpis__metric_daily_api_billable_verifications.sql @@ -0,0 +1,14 @@ +{{ config(materialized="table", unique_key=["date", "id_deal", "service_name"]) }} + +select + -- Unique Key -- + iuav.billable_date_utc as date, + coalesce(iuav.id_deal, 'UNSET') as id_deal, + coalesce(iuav.api_source, 'UNSET') as service_name, + -- Dimensions -- + 'API' as business_scope, + -- Metrics -- + count(distinct iuav.id_verification) as billable_verifications +from {{ ref("int_unified_api_verifications") }} iuav +where iuav.billable_date_utc is not null +group by 1, 2, 3, 4 diff --git a/models/intermediate/kpis/int_kpis__metric_monthly_api_billable_verifications.sql b/models/intermediate/kpis/int_kpis__metric_monthly_api_billable_verifications.sql new file mode 100644 index 0000000..e439783 --- /dev/null +++ b/models/intermediate/kpis/int_kpis__metric_monthly_api_billable_verifications.sql @@ -0,0 +1,27 @@ +{{ + config( + materialized="view", + unique_key=[ + "end_date", + "id_deal", + "service_name", + ], + ) +}} + +select + -- Unique Key -- + d.first_day_month as start_date, + d.date as end_date, + b.id_deal, + b.service_name, + -- Dimensions -- + b.business_scope, + -- Metrics -- + sum(b.billable_verifications) as billable_verifications +from {{ ref("int_kpis__dimension_dates") }} d +left join + {{ ref("int_kpis__metric_daily_api_billable_verifications") }} b + on date_trunc('month', b.date)::date = d.first_day_month +where d.is_end_of_month = true and b.id_deal is not null +group by 1, 2, 3, 4, 5 diff --git a/models/intermediate/kpis/schema.yml b/models/intermediate/kpis/schema.yml index 0be83a7..ccc08e0 100644 --- a/models/intermediate/kpis/schema.yml +++ b/models/intermediate/kpis/schema.yml @@ -8834,3 +8834,233 @@ models: - Rolling up the total onboarding MRR for each listing segment to get the total onboarding MRR for the Global dimension. This is not available for 'by_billing_country' dimension, thus null values are expected. + + - name: int_kpis__metric_daily_api_billable_verifications + description: | + This model computes the Daily Billable Verifications from APIs at + the deepest granularity. + + The unique key corresponds to the deepest granularity of the model, + in this case: + - date, + - id_deal, + - service_name. + + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - date + - id_deal + - service_name + + columns: + - name: date + data_type: date + description: Date of when Verifications have been billable. + data_tests: + - not_null + + - name: id_deal + data_type: string + description: Unique identifier of an account. + data_tests: + - not_null + + - name: business_scope + data_type: string + description: | + Business scope identifying the metric source. + data_tests: + - not_null + - accepted_values: + values: + - "API" + + - name: service_name + data_type: string + description: | + Name of the API service that has been billable. + data_tests: + - not_null + - accepted_values: + values: + - "ATHENA" + - "E-DEPOSIT" + - "CHECK_IN_HERO" + - "SCREEN_AND_PROTECT" + + - name: billable_verifications + data_type: bigint + description: | + Count of daily verifications billable in a given date and per specified dimension. + + - name: int_kpis__agg_daily_api_billable_verifications + description: | + This model computes the dimension aggregation for + Daily Billable Verifications, from APIs. + + The primary key of this model is date, dimension + and dimension_value. + + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - date + - dimension + - dimension_value + + columns: + - name: date + data_type: date + description: | + The start and end date of the time range considered for + the metrics in this record. + data_tests: + - not_null + + - name: dimension + data_type: string + description: The dimension or granularity of the metrics. + data_tests: + - assert_dimension_completeness: + metric_column_names: + - billable_verifications + - accepted_values: + values: + - global + - by_service + - by_business_scope + - by_deal + + - name: dimension_value + data_type: string + description: The value or segment available for the selected dimension. + data_tests: + - not_null + + - name: billable_verifications + data_type: bigint + description: The daily billable verifications for a given date, dimension and value. + + - name: int_kpis__metric_monthly_api_billable_verifications + description: | + This model computes the Monthly Billable Verifications from APIs at + the deepest granularity. + + The unique key corresponds to the deepest granularity of the model, + in this case: + - end_date, + - id_deal, + - service_name. + + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - end_date + - id_deal + - service_name + + columns: + - name: start_date + data_type: date + description: | + The start date of the time range considered for the metrics in this record. + data_tests: + - not_null + + - name: end_date + data_type: date + description: | + The end date of the time range considered for the metrics in this record. + data_tests: + - not_null + + - name: id_deal + data_type: string + description: Unique identifier of an account. + data_tests: + - not_null + + - name: business_scope + data_type: string + description: | + Business scope identifying the metric source. + data_tests: + - not_null + - accepted_values: + values: + - "API" + + - name: service_name + data_type: string + description: | + Name of the API service that has been billable. + data_tests: + - not_null + - accepted_values: + values: + - "ATHENA" + - "E-DEPOSIT" + - "CHECK_IN_HERO" + - "SCREEN_AND_PROTECT" + + - name: billable_verifications + data_type: bigint + description: | + Count of monthly verifications billable in a given month and per + specified dimension. + + - name: int_kpis__agg_monthly_api_billable_verifications + description: | + This model computes the dimension aggregation for + Monthly Billable Verifications, from APIs. + + The primary key of this model is end_date, dimension + and dimension_value. + + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - end_date + - dimension + - dimension_value + + columns: + - name: start_date + data_type: date + description: | + The start date of the time range considered for the metrics in this record. + data_tests: + - not_null + + - name: end_date + data_type: date + description: | + The end date of the time range considered for the metrics in this record. + data_tests: + - not_null + + - name: dimension + data_type: string + description: The dimension or granularity of the metrics. + data_tests: + - assert_dimension_completeness: + metric_column_names: + - billable_verifications + - accepted_values: + values: + - global + - by_service + - by_business_scope + - by_deal + + - name: dimension_value + data_type: string + description: The value or segment available for the selected dimension. + data_tests: + - not_null + + - name: billable_verifications + data_type: bigint + description: | + The monthly billable verifications for a given date, dimension and value.