Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DENG-3274 Add login funnel based on event metrics #5928

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions sql_generators/funnels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ def generate_funnels(target_project, path, output_dir):
config = converter.structure(toml.load(config_file), FunnelConfig)
table_name = bq_normalize_name(config_file.stem)

match = re.match(r".+_v(\d+)$", table_name)
if match:
# file name ends with version number, check if it matches the version in the config
name_version = match.groups()[0]
if name_version != config.version:
raise ValueError(
f"Version in file name ({table_name}) does not match version in config ({config.version})"
)
else:
table_name = f"{table_name}_v{config.version}"

env = Environment(loader=FileSystemLoader(TEMPLATES_PATH))
sql_template = env.get_template("funnel.sql")

Expand All @@ -45,7 +56,7 @@ def generate_funnels(target_project, path, output_dir):
)
write_sql(
output_dir=output_dir,
full_table_id=f"{target_project}.{config.destination_dataset}.{table_name}_v{config.version}",
full_table_id=f"{target_project}.{config.destination_dataset}.{table_name}",
basename="query.sql",
sql=funnel_sql,
skip_existing=False,
Expand All @@ -59,10 +70,7 @@ def generate_funnels(target_project, path, output_dir):
}
)
(
output_dir
/ config.destination_dataset
/ f"{table_name}_v{config.version}"
/ "metadata.yaml"
output_dir / config.destination_dataset / f"{table_name}" / "metadata.yaml"
).write_text(rendered_metadata + "\n")


Expand Down
148 changes: 148 additions & 0 deletions sql_generators/funnels/configs/login_funnels_by_service_v2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
destination_dataset = "accounts_frontend_derived"
platform = "accounts_frontend"
owners = ["[email protected]"] # optional; users getting notification if funnel run fails
version = "2"
start_date = "2024-01-01"

[funnels]

[funnels.login_overall_success_by_service]

friendly_name = "Login Funnel Conversion by Service"
description = "Overall login funnel conversion rates by Service"
steps = ["login_view", "login_complete"]
dimensions = ["service"]

[funnels.login_submit_overall_success_by_service]

friendly_name = "Login Funnel Conversion with Submit Events by Service"
description = "Overall login funnel conversion rates by Service"
steps = ["login_view", "login_submit", "login_success", "login_complete"]
dimensions = ["service"]

[funnels.login_success_with_email_by_service]

friendly_name = "Login Funnel Conversion by Service with Email Confirmation Step"
description = "Overall login funnel conversion rates by Service including email confirmation step"
steps = ["login_view", "login_submit", "login_success", "login_email_confirmation_view", "login_email_confirmation_submit", "login_email_confirmation_success", "login_complete"]
dimensions = ["service"]

[funnels.login_success_with_2fa_by_service]

friendly_name = "Login Funnel Conversion with 2FA Step by Service"
description = "Funnel steps from Login View through 2FA (no backup codes) by Service"
steps = ["login_view", "login_submit", "login_success", "login_two_factor_view", "login_two_factor_submit", "login_two_factor_success", "login_complete"]
dimensions = ["service"]

[steps]

[steps.login_view]
friendly_name = "Login View Form"
description = "View of the top of the login funnel"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.view' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_submit]
friendly_name = "Login Submit"
description = "Attempt to submit login form"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.submit' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_success]
friendly_name = "Login Success"
description = "Successful password submission on login form"
data_source = "accounts_backend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.success' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_email_confirmation_view]
friendly_name = "Login Email Confirmation View"
description = "View of the email confirmaition form for login"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.email_confirmation_view' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_email_confirmation_submit]
friendly_name = "Login Email Confirmation Submit"
description = "The user successfully attempted to submit the email confirmation form"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.email_confirmation_submit' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_email_confirmation_success]
friendly_name = "Successful Email Confirmation"
description = "The user successfully confirmed their email in login flow"
data_source = "accounts_backend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.email_confirmation_success' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_two_factor_view]
friendly_name = "Login 2FA Form"
description = "View of the login 2FA form"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.totp_form_view' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_two_factor_submit]
friendly_name = "Attempt to submit login 2FA form"
description = "The user successfully authenticated through 2FA"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.totp_code_submit' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_two_factor_success]
friendly_name = "Login 2FA Success"
description = "Successful submission of 2FA form"
data_source = "accounts_frontend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.totp_code_success_view' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[steps.login_complete]
friendly_name = "Successful Login Completion"
description = "The login flow was completed successfully"
data_source = "accounts_backend"
select_expression = "metrics.string.session_flow_id"
where_expression = "event = 'login.complete' AND metrics.string.session_flow_id != ''"
aggregation = "count distinct"
join_previous_step_on = "metrics.string.session_flow_id"

[data_sources]

[data_sources.accounts_frontend]
from_expression = "mozdata.accounts_frontend.events_stream AS es"
submission_date_column = "DATE(submission_timestamp)"
client_id_column = "es.client_id"

[data_sources.accounts_backend]
from_expression = "mozdata.accounts_backend.events_stream AS es"
submission_date_column = "DATE(submission_timestamp)"
client_id_column = "es.client_id"

[dimensions]

[dimensions.service]
data_source = "accounts_frontend"
select_expression = "IF(COALESCE(NULLIF(metrics.string.relying_party_oauth_client_id, ''), NULLIF(metrics.string.relying_party_service, '')) = 'sync', '5882386c6d801776', COALESCE(NULLIF(metrics.string.relying_party_oauth_client_id, ''), NULLIF(metrics.string.relying_party_service, '')))"
friendly_name = "Service"
description = "Oauth Client ID is used to map to service name for which service the user logged in through"
client_id_column = "client_id"