diff --git a/crates/analytics/src/auth_events/core.rs b/crates/analytics/src/auth_events/core.rs index bdcbdd86a9..4d11f19d53 100644 --- a/crates/analytics/src/auth_events/core.rs +++ b/crates/analytics/src/auth_events/core.rs @@ -169,6 +169,7 @@ pub async fn get_filters( AuthEventDimensions::ErrorMessage => fil.error_message, AuthEventDimensions::AuthenticationConnector => fil.authentication_connector.map(|i| i.as_ref().to_string()), AuthEventDimensions::MessageVersion => fil.message_version, + AuthEventDimensions::AcsReferenceNumber => fil.acs_reference_number, }) .collect::>(); res.query_data.push(AuthEventFilterValue { diff --git a/crates/analytics/src/auth_events/filters.rs b/crates/analytics/src/auth_events/filters.rs index 5f65eeaa27..1961116b84 100644 --- a/crates/analytics/src/auth_events/filters.rs +++ b/crates/analytics/src/auth_events/filters.rs @@ -59,4 +59,5 @@ pub struct AuthEventFilterRow { pub error_message: Option, pub authentication_connector: Option>, pub message_version: Option, + pub acs_reference_number: Option, } diff --git a/crates/analytics/src/auth_events/metrics.rs b/crates/analytics/src/auth_events/metrics.rs index a3d0fe7b68..6315c1338e 100644 --- a/crates/analytics/src/auth_events/metrics.rs +++ b/crates/analytics/src/auth_events/metrics.rs @@ -45,6 +45,7 @@ pub struct AuthEventMetricRow { pub error_message: Option, pub authentication_connector: Option>, pub message_version: Option, + pub acs_reference_number: Option, #[serde(with = "common_utils::custom_serde::iso8601::option")] pub start_bucket: Option, #[serde(with = "common_utils::custom_serde::iso8601::option")] diff --git a/crates/analytics/src/auth_events/metrics/authentication_attempt_count.rs b/crates/analytics/src/auth_events/metrics/authentication_attempt_count.rs index b82d1ef4c3..fbdc4b75b3 100644 --- a/crates/analytics/src/auth_events/metrics/authentication_attempt_count.rs +++ b/crates/analytics/src/auth_events/metrics/authentication_attempt_count.rs @@ -110,6 +110,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/authentication_count.rs b/crates/analytics/src/auth_events/metrics/authentication_count.rs index 682e8a07f6..b4c0a5c595 100644 --- a/crates/analytics/src/auth_events/metrics/authentication_count.rs +++ b/crates/analytics/src/auth_events/metrics/authentication_count.rs @@ -100,6 +100,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/authentication_error_message.rs b/crates/analytics/src/auth_events/metrics/authentication_error_message.rs index 047511d477..b064cb7ab3 100644 --- a/crates/analytics/src/auth_events/metrics/authentication_error_message.rs +++ b/crates/analytics/src/auth_events/metrics/authentication_error_message.rs @@ -119,6 +119,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/authentication_funnel.rs b/crates/analytics/src/auth_events/metrics/authentication_funnel.rs index 9342e9047e..3a122fd42a 100644 --- a/crates/analytics/src/auth_events/metrics/authentication_funnel.rs +++ b/crates/analytics/src/auth_events/metrics/authentication_funnel.rs @@ -111,6 +111,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/authentication_success_count.rs b/crates/analytics/src/auth_events/metrics/authentication_success_count.rs index 984350efe6..3743512362 100644 --- a/crates/analytics/src/auth_events/metrics/authentication_success_count.rs +++ b/crates/analytics/src/auth_events/metrics/authentication_success_count.rs @@ -105,6 +105,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/challenge_attempt_count.rs b/crates/analytics/src/auth_events/metrics/challenge_attempt_count.rs index 5a2a9400b2..0265fc7e45 100644 --- a/crates/analytics/src/auth_events/metrics/challenge_attempt_count.rs +++ b/crates/analytics/src/auth_events/metrics/challenge_attempt_count.rs @@ -115,6 +115,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/challenge_flow_count.rs b/crates/analytics/src/auth_events/metrics/challenge_flow_count.rs index 279844388f..178dcba20b 100644 --- a/crates/analytics/src/auth_events/metrics/challenge_flow_count.rs +++ b/crates/analytics/src/auth_events/metrics/challenge_flow_count.rs @@ -107,6 +107,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/challenge_success_count.rs b/crates/analytics/src/auth_events/metrics/challenge_success_count.rs index 91e8cc5428..b78f84326d 100644 --- a/crates/analytics/src/auth_events/metrics/challenge_success_count.rs +++ b/crates/analytics/src/auth_events/metrics/challenge_success_count.rs @@ -112,6 +112,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/frictionless_flow_count.rs b/crates/analytics/src/auth_events/metrics/frictionless_flow_count.rs index b08edb1011..d114e36f14 100644 --- a/crates/analytics/src/auth_events/metrics/frictionless_flow_count.rs +++ b/crates/analytics/src/auth_events/metrics/frictionless_flow_count.rs @@ -108,6 +108,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/metrics/frictionless_success_count.rs b/crates/analytics/src/auth_events/metrics/frictionless_success_count.rs index 80417ac64b..a56d5b660a 100644 --- a/crates/analytics/src/auth_events/metrics/frictionless_success_count.rs +++ b/crates/analytics/src/auth_events/metrics/frictionless_success_count.rs @@ -112,6 +112,7 @@ where i.error_message.clone(), i.authentication_connector.as_ref().map(|i| i.0), i.message_version.clone(), + i.acs_reference_number.clone(), TimeRange { start_time: match (granularity, i.start_bucket) { (Some(g), Some(st)) => g.clip_to_start(st)?, diff --git a/crates/analytics/src/auth_events/types.rs b/crates/analytics/src/auth_events/types.rs index ac7ee2462e..863e50a0af 100644 --- a/crates/analytics/src/auth_events/types.rs +++ b/crates/analytics/src/auth_events/types.rs @@ -53,6 +53,15 @@ where ) .attach_printable("Error adding message version filter")?; } + + if !self.acs_reference_number.is_empty() { + builder + .add_filter_in_range_clause( + AuthEventDimensions::AcsReferenceNumber, + &self.acs_reference_number, + ) + .attach_printable("Error adding acs reference number filter")?; + } Ok(()) } } diff --git a/crates/analytics/src/sqlx.rs b/crates/analytics/src/sqlx.rs index 6a6237e678..5a2f097bb0 100644 --- a/crates/analytics/src/sqlx.rs +++ b/crates/analytics/src/sqlx.rs @@ -231,6 +231,11 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::metrics::AuthEventMetricRow ColumnNotFound(_) => Ok(Default::default()), e => Err(e), })?; + let acs_reference_number: Option = + row.try_get("acs_reference_number").or_else(|e| match e { + ColumnNotFound(_) => Ok(Default::default()), + e => Err(e), + })?; let count: Option = row.try_get("count").or_else(|e| match e { ColumnNotFound(_) => Ok(Default::default()), e => Err(e), @@ -249,6 +254,7 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::metrics::AuthEventMetricRow error_message, authentication_connector, message_version, + acs_reference_number, count, start_bucket, end_bucket, @@ -288,6 +294,11 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::filters::AuthEventFilterRow ColumnNotFound(_) => Ok(Default::default()), e => Err(e), })?; + let acs_reference_number: Option = + row.try_get("acs_reference_number").or_else(|e| match e { + ColumnNotFound(_) => Ok(Default::default()), + e => Err(e), + })?; Ok(Self { authentication_status, trans_status, @@ -295,6 +306,7 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::filters::AuthEventFilterRow error_message, authentication_connector, message_version, + acs_reference_number, }) } } diff --git a/crates/analytics/src/utils.rs b/crates/analytics/src/utils.rs index a0ddead136..0832788e26 100644 --- a/crates/analytics/src/utils.rs +++ b/crates/analytics/src/utils.rs @@ -51,6 +51,7 @@ pub fn get_auth_event_dimensions() -> Vec { vec![ AuthEventDimensions::AuthenticationConnector, AuthEventDimensions::MessageVersion, + AuthEventDimensions::AcsReferenceNumber, ] .into_iter() .map(Into::into) diff --git a/crates/api_models/src/analytics/auth_events.rs b/crates/api_models/src/analytics/auth_events.rs index 2360e56464..8a1c168aa2 100644 --- a/crates/api_models/src/analytics/auth_events.rs +++ b/crates/api_models/src/analytics/auth_events.rs @@ -23,6 +23,8 @@ pub struct AuthEventFilters { pub authentication_connector: Vec, #[serde(default)] pub message_version: Vec, + #[serde(default)] + pub acs_reference_number: Vec, } #[derive( @@ -50,6 +52,7 @@ pub enum AuthEventDimensions { ErrorMessage, AuthenticationConnector, MessageVersion, + AcsReferenceNumber, } #[derive( @@ -135,6 +138,7 @@ pub struct AuthEventMetricsBucketIdentifier { pub error_message: Option, pub authentication_connector: Option, pub message_version: Option, + pub acs_reference_number: Option, #[serde(rename = "time_range")] pub time_bucket: TimeRange, #[serde(rename = "time_bucket")] @@ -151,6 +155,7 @@ impl AuthEventMetricsBucketIdentifier { error_message: Option, authentication_connector: Option, message_version: Option, + acs_reference_number: Option, normalized_time_range: TimeRange, ) -> Self { Self { @@ -160,6 +165,7 @@ impl AuthEventMetricsBucketIdentifier { error_message, authentication_connector, message_version, + acs_reference_number, time_bucket: normalized_time_range, start_time: normalized_time_range.start_time, } @@ -173,6 +179,7 @@ impl Hash for AuthEventMetricsBucketIdentifier { self.authentication_type.hash(state); self.authentication_connector.hash(state); self.message_version.hash(state); + self.acs_reference_number.hash(state); self.error_message.hash(state); self.time_bucket.hash(state); }