mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat(analytics): refactor and rewrite authentication related analytics (#7433)
Co-authored-by: Sandeep Kumar <sandeep.kumar@Sandeep-Kumar-LVF93XQXPC.local>
This commit is contained in:
@ -4,7 +4,7 @@ use super::metrics::AuthEventMetricRow;
|
|||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct AuthEventMetricsAccumulator {
|
pub struct AuthEventMetricsAccumulator {
|
||||||
pub three_ds_sdk_count: CountAccumulator,
|
pub authentication_count: CountAccumulator,
|
||||||
pub authentication_attempt_count: CountAccumulator,
|
pub authentication_attempt_count: CountAccumulator,
|
||||||
pub authentication_success_count: CountAccumulator,
|
pub authentication_success_count: CountAccumulator,
|
||||||
pub challenge_flow_count: CountAccumulator,
|
pub challenge_flow_count: CountAccumulator,
|
||||||
@ -47,7 +47,7 @@ impl AuthEventMetricAccumulator for CountAccumulator {
|
|||||||
impl AuthEventMetricsAccumulator {
|
impl AuthEventMetricsAccumulator {
|
||||||
pub fn collect(self) -> AuthEventMetricsBucketValue {
|
pub fn collect(self) -> AuthEventMetricsBucketValue {
|
||||||
AuthEventMetricsBucketValue {
|
AuthEventMetricsBucketValue {
|
||||||
three_ds_sdk_count: self.three_ds_sdk_count.collect(),
|
authentication_count: self.authentication_count.collect(),
|
||||||
authentication_attempt_count: self.authentication_attempt_count.collect(),
|
authentication_attempt_count: self.authentication_attempt_count.collect(),
|
||||||
authentication_success_count: self.authentication_success_count.collect(),
|
authentication_success_count: self.authentication_success_count.collect(),
|
||||||
challenge_flow_count: self.challenge_flow_count.collect(),
|
challenge_flow_count: self.challenge_flow_count.collect(),
|
||||||
|
|||||||
@ -18,7 +18,6 @@ use crate::{
|
|||||||
pub async fn get_metrics(
|
pub async fn get_metrics(
|
||||||
pool: &AnalyticsProvider,
|
pool: &AnalyticsProvider,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &String,
|
|
||||||
req: GetAuthEventMetricRequest,
|
req: GetAuthEventMetricRequest,
|
||||||
) -> AnalyticsResult<MetricsResponse<MetricsBucketResponse>> {
|
) -> AnalyticsResult<MetricsResponse<MetricsBucketResponse>> {
|
||||||
let mut metrics_accumulator: HashMap<
|
let mut metrics_accumulator: HashMap<
|
||||||
@ -30,14 +29,12 @@ pub async fn get_metrics(
|
|||||||
for metric_type in req.metrics.iter().cloned() {
|
for metric_type in req.metrics.iter().cloned() {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let merchant_id_scoped = merchant_id.to_owned();
|
let merchant_id_scoped = merchant_id.to_owned();
|
||||||
let publishable_key_scoped = publishable_key.to_owned();
|
|
||||||
let pool = pool.clone();
|
let pool = pool.clone();
|
||||||
set.spawn(async move {
|
set.spawn(async move {
|
||||||
let data = pool
|
let data = pool
|
||||||
.get_auth_event_metrics(
|
.get_auth_event_metrics(
|
||||||
&metric_type,
|
&metric_type,
|
||||||
&merchant_id_scoped,
|
&merchant_id_scoped,
|
||||||
&publishable_key_scoped,
|
|
||||||
req.time_series.map(|t| t.granularity),
|
req.time_series.map(|t| t.granularity),
|
||||||
&req.time_range,
|
&req.time_range,
|
||||||
)
|
)
|
||||||
@ -56,8 +53,8 @@ pub async fn get_metrics(
|
|||||||
for (id, value) in data? {
|
for (id, value) in data? {
|
||||||
let metrics_builder = metrics_accumulator.entry(id).or_default();
|
let metrics_builder = metrics_accumulator.entry(id).or_default();
|
||||||
match metric {
|
match metric {
|
||||||
AuthEventMetrics::ThreeDsSdkCount => metrics_builder
|
AuthEventMetrics::AuthenticationCount => metrics_builder
|
||||||
.three_ds_sdk_count
|
.authentication_count
|
||||||
.add_metrics_bucket(&value),
|
.add_metrics_bucket(&value),
|
||||||
AuthEventMetrics::AuthenticationAttemptCount => metrics_builder
|
AuthEventMetrics::AuthenticationAttemptCount => metrics_builder
|
||||||
.authentication_attempt_count
|
.authentication_attempt_count
|
||||||
|
|||||||
@ -12,22 +12,22 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
mod authentication_attempt_count;
|
mod authentication_attempt_count;
|
||||||
|
mod authentication_count;
|
||||||
mod authentication_success_count;
|
mod authentication_success_count;
|
||||||
mod challenge_attempt_count;
|
mod challenge_attempt_count;
|
||||||
mod challenge_flow_count;
|
mod challenge_flow_count;
|
||||||
mod challenge_success_count;
|
mod challenge_success_count;
|
||||||
mod frictionless_flow_count;
|
mod frictionless_flow_count;
|
||||||
mod frictionless_success_count;
|
mod frictionless_success_count;
|
||||||
mod three_ds_sdk_count;
|
|
||||||
|
|
||||||
use authentication_attempt_count::AuthenticationAttemptCount;
|
use authentication_attempt_count::AuthenticationAttemptCount;
|
||||||
|
use authentication_count::AuthenticationCount;
|
||||||
use authentication_success_count::AuthenticationSuccessCount;
|
use authentication_success_count::AuthenticationSuccessCount;
|
||||||
use challenge_attempt_count::ChallengeAttemptCount;
|
use challenge_attempt_count::ChallengeAttemptCount;
|
||||||
use challenge_flow_count::ChallengeFlowCount;
|
use challenge_flow_count::ChallengeFlowCount;
|
||||||
use challenge_success_count::ChallengeSuccessCount;
|
use challenge_success_count::ChallengeSuccessCount;
|
||||||
use frictionless_flow_count::FrictionlessFlowCount;
|
use frictionless_flow_count::FrictionlessFlowCount;
|
||||||
use frictionless_success_count::FrictionlessSuccessCount;
|
use frictionless_success_count::FrictionlessSuccessCount;
|
||||||
use three_ds_sdk_count::ThreeDsSdkCount;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, serde::Deserialize, Hash)]
|
#[derive(Debug, PartialEq, Eq, serde::Deserialize, Hash)]
|
||||||
pub struct AuthEventMetricRow {
|
pub struct AuthEventMetricRow {
|
||||||
@ -45,7 +45,6 @@ where
|
|||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
@ -65,50 +64,49 @@ where
|
|||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
match self {
|
match self {
|
||||||
Self::ThreeDsSdkCount => {
|
Self::AuthenticationCount => {
|
||||||
ThreeDsSdkCount
|
AuthenticationCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::AuthenticationAttemptCount => {
|
Self::AuthenticationAttemptCount => {
|
||||||
AuthenticationAttemptCount
|
AuthenticationAttemptCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::AuthenticationSuccessCount => {
|
Self::AuthenticationSuccessCount => {
|
||||||
AuthenticationSuccessCount
|
AuthenticationSuccessCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::ChallengeFlowCount => {
|
Self::ChallengeFlowCount => {
|
||||||
ChallengeFlowCount
|
ChallengeFlowCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::ChallengeAttemptCount => {
|
Self::ChallengeAttemptCount => {
|
||||||
ChallengeAttemptCount
|
ChallengeAttemptCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::ChallengeSuccessCount => {
|
Self::ChallengeSuccessCount => {
|
||||||
ChallengeSuccessCount
|
ChallengeSuccessCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::FrictionlessFlowCount => {
|
Self::FrictionlessFlowCount => {
|
||||||
FrictionlessFlowCount
|
FrictionlessFlowCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::FrictionlessSuccessCount => {
|
Self::FrictionlessSuccessCount => {
|
||||||
FrictionlessSuccessCount
|
FrictionlessSuccessCount
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::AuthEventMetricsBucketIdentifier, sdk_events::SdkEventNames, Granularity,
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
TimeRange,
|
|
||||||
};
|
};
|
||||||
|
use common_enums::AuthenticationStatus;
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
@ -29,14 +29,13 @@ where
|
|||||||
{
|
{
|
||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,30 +44,26 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", publishable_key)
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_bool_filter_clause("first_event", 1)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("event_name", SdkEventNames::AuthenticationCallInit)
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("log_type", "INFO")
|
.add_negative_filter_clause("authentication_status", AuthenticationStatus::Pending)
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("category", "API")
|
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -76,9 +71,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::AuthEventMetricsBucketIdentifier, sdk_events::SdkEventNames, Granularity,
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
TimeRange,
|
|
||||||
};
|
};
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
@ -15,10 +14,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(super) struct ThreeDsSdkCount;
|
pub(super) struct AuthenticationCount;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<T> super::AuthEventMetric<T> for ThreeDsSdkCount
|
impl<T> super::AuthEventMetric<T> for AuthenticationCount
|
||||||
where
|
where
|
||||||
T: AnalyticsDataSource + super::AuthEventMetricAnalytics,
|
T: AnalyticsDataSource + super::AuthEventMetricAnalytics,
|
||||||
PrimitiveDateTime: ToSql<T>,
|
PrimitiveDateTime: ToSql<T>,
|
||||||
@ -29,14 +28,13 @@ where
|
|||||||
{
|
{
|
||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,30 +43,22 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", publishable_key)
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_bool_filter_clause("first_event", 1)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("category", "USER_EVENT")
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("log_type", "INFO")
|
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("event_name", SdkEventNames::ThreeDsMethod)
|
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -76,9 +66,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::AuthEventMetricsBucketIdentifier, sdk_events::SdkEventNames, Granularity,
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
TimeRange,
|
|
||||||
};
|
};
|
||||||
|
use common_enums::AuthenticationStatus;
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
@ -29,14 +29,13 @@ where
|
|||||||
{
|
{
|
||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,30 +44,26 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", publishable_key)
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_bool_filter_clause("first_event", 1)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("event_name", SdkEventNames::AuthenticationCall)
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("log_type", "INFO")
|
.add_filter_clause("authentication_status", AuthenticationStatus::Success)
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("category", "API")
|
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -76,9 +71,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::{AuthEventFlows, AuthEventMetricsBucketIdentifier},
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
Granularity, TimeRange,
|
|
||||||
};
|
};
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
@ -10,7 +9,7 @@ use time::PrimitiveDateTime;
|
|||||||
|
|
||||||
use super::AuthEventMetricRow;
|
use super::AuthEventMetricRow;
|
||||||
use crate::{
|
use crate::{
|
||||||
query::{Aggregate, FilterTypes, GroupByClause, QueryBuilder, QueryFilter, ToSql, Window},
|
query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, ToSql, Window},
|
||||||
types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
|
types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,13 +29,12 @@ where
|
|||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
_publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::ApiEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,22 +43,30 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
query_builder
|
||||||
query_builder
|
.add_select_column(Aggregate::Min {
|
||||||
.add_granularity_in_mins(granularity)
|
field: "created_at",
|
||||||
.switch()?;
|
alias: Some("start_bucket"),
|
||||||
}
|
})
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
|
query_builder
|
||||||
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", merchant_id)
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("api_flow", AuthEventFlows::IncomingWebhookReceive)
|
.add_filter_clause("trans_status", "C".to_string())
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_custom_filter_clause("request", "threeDSServerTransID", FilterTypes::Like)
|
.add_negative_filter_clause("authentication_status", "pending")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -68,9 +74,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::AuthEventMetricsBucketIdentifier, sdk_events::SdkEventNames, Granularity,
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
TimeRange,
|
|
||||||
};
|
};
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
@ -29,14 +28,13 @@ where
|
|||||||
{
|
{
|
||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,42 +43,36 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", publishable_key)
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_bool_filter_clause("first_event", 1)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("category", "USER_EVENT")
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("log_type", "INFO")
|
.add_filter_clause("trans_status", "C".to_string())
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("event_name", SdkEventNames::DisplayThreeDsSdk)
|
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder.add_filter_clause("value", "C").switch()?;
|
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
.set_filter_clause(&mut query_builder)
|
.set_filter_clause(&mut query_builder)
|
||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::{AuthEventFlows, AuthEventMetricsBucketIdentifier},
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
Granularity, TimeRange,
|
|
||||||
};
|
};
|
||||||
|
use common_enums::AuthenticationStatus;
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
@ -30,13 +30,12 @@ where
|
|||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
_publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::ApiEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,22 +44,30 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
query_builder
|
||||||
query_builder
|
.add_select_column(Aggregate::Min {
|
||||||
.add_granularity_in_mins(granularity)
|
field: "created_at",
|
||||||
.switch()?;
|
alias: Some("start_bucket"),
|
||||||
}
|
})
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
|
query_builder
|
||||||
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", merchant_id)
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("api_flow", AuthEventFlows::IncomingWebhookReceive)
|
.add_filter_clause("authentication_status", AuthenticationStatus::Success)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("visitParamExtractRaw(request, 'transStatus')", "\"Y\"")
|
.add_filter_clause("trans_status", "C".to_string())
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -68,9 +75,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::AuthEventMetricsBucketIdentifier, sdk_events::SdkEventNames, Granularity,
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
TimeRange,
|
|
||||||
};
|
};
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
@ -29,14 +28,13 @@ where
|
|||||||
{
|
{
|
||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,34 +43,26 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", publishable_key)
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_bool_filter_clause("first_event", 1)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("category", "USER_EVENT")
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("log_type", "INFO")
|
.add_filter_clause("trans_status", "Y".to_string())
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_filter_clause("event_name", SdkEventNames::DisplayThreeDsSdk)
|
|
||||||
.switch()?;
|
|
||||||
|
|
||||||
query_builder
|
|
||||||
.add_negative_filter_clause("value", "C")
|
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -80,9 +70,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use api_models::analytics::{
|
use api_models::analytics::{
|
||||||
auth_events::{AuthEventFlows, AuthEventMetricsBucketIdentifier},
|
auth_events::AuthEventMetricsBucketIdentifier, Granularity, TimeRange,
|
||||||
Granularity, TimeRange,
|
|
||||||
};
|
};
|
||||||
|
use common_enums::AuthenticationStatus;
|
||||||
use common_utils::errors::ReportSwitchExt;
|
use common_utils::errors::ReportSwitchExt;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
@ -30,13 +30,12 @@ where
|
|||||||
async fn load_metrics(
|
async fn load_metrics(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
_publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
pool: &T,
|
pool: &T,
|
||||||
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
let mut query_builder: QueryBuilder<T> =
|
let mut query_builder: QueryBuilder<T> =
|
||||||
QueryBuilder::new(AnalyticsCollection::ApiEventsAnalytics);
|
QueryBuilder::new(AnalyticsCollection::Authentications);
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_select_column(Aggregate::Count {
|
.add_select_column(Aggregate::Count {
|
||||||
@ -45,22 +44,30 @@ where
|
|||||||
})
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(granularity) = granularity {
|
|
||||||
query_builder
|
|
||||||
.add_granularity_in_mins(granularity)
|
|
||||||
.switch()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("merchant_id", merchant_id.get_string_repr())
|
.add_select_column(Aggregate::Min {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("start_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("api_flow", AuthEventFlows::PaymentsExternalAuthentication)
|
.add_select_column(Aggregate::Max {
|
||||||
|
field: "created_at",
|
||||||
|
alias: Some("end_bucket"),
|
||||||
|
})
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
query_builder
|
query_builder
|
||||||
.add_filter_clause("visitParamExtractRaw(response, 'transStatus')", "\"Y\"")
|
.add_filter_clause("merchant_id", merchant_id)
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
|
query_builder
|
||||||
|
.add_filter_clause("trans_status", "Y".to_string())
|
||||||
|
.switch()?;
|
||||||
|
|
||||||
|
query_builder
|
||||||
|
.add_filter_clause("authentication_status", AuthenticationStatus::Success)
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
time_range
|
time_range
|
||||||
@ -68,9 +75,9 @@ where
|
|||||||
.attach_printable("Error filtering time range")
|
.attach_printable("Error filtering time range")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
|
|
||||||
if let Some(_granularity) = granularity.as_ref() {
|
if let Some(granularity) = granularity {
|
||||||
query_builder
|
granularity
|
||||||
.add_group_by_clause("time_bucket")
|
.set_group_by_clause(&mut query_builder)
|
||||||
.attach_printable("Error adding granularity")
|
.attach_printable("Error adding granularity")
|
||||||
.switch()?;
|
.switch()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -138,6 +138,7 @@ impl AnalyticsDataSource for ClickhouseClient {
|
|||||||
| AnalyticsCollection::FraudCheck
|
| AnalyticsCollection::FraudCheck
|
||||||
| AnalyticsCollection::PaymentIntent
|
| AnalyticsCollection::PaymentIntent
|
||||||
| AnalyticsCollection::PaymentIntentSessionized
|
| AnalyticsCollection::PaymentIntentSessionized
|
||||||
|
| AnalyticsCollection::Authentications
|
||||||
| AnalyticsCollection::Dispute => {
|
| AnalyticsCollection::Dispute => {
|
||||||
TableEngine::CollapsingMergeTree { sign: "sign_flag" }
|
TableEngine::CollapsingMergeTree { sign: "sign_flag" }
|
||||||
}
|
}
|
||||||
@ -457,6 +458,7 @@ impl ToSql<ClickhouseClient> for AnalyticsCollection {
|
|||||||
Self::Dispute => Ok("dispute".to_string()),
|
Self::Dispute => Ok("dispute".to_string()),
|
||||||
Self::DisputeSessionized => Ok("sessionizer_dispute".to_string()),
|
Self::DisputeSessionized => Ok("sessionizer_dispute".to_string()),
|
||||||
Self::ActivePaymentsAnalytics => Ok("active_payments".to_string()),
|
Self::ActivePaymentsAnalytics => Ok("active_payments".to_string()),
|
||||||
|
Self::Authentications => Ok("authentications".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -909,7 +909,6 @@ impl AnalyticsProvider {
|
|||||||
&self,
|
&self,
|
||||||
metric: &AuthEventMetrics,
|
metric: &AuthEventMetrics,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
publishable_key: &str,
|
|
||||||
granularity: Option<Granularity>,
|
granularity: Option<Granularity>,
|
||||||
time_range: &TimeRange,
|
time_range: &TimeRange,
|
||||||
) -> types::MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
) -> types::MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
|
||||||
@ -917,14 +916,13 @@ impl AnalyticsProvider {
|
|||||||
Self::Sqlx(_pool) => Err(report!(MetricsError::NotImplemented)),
|
Self::Sqlx(_pool) => Err(report!(MetricsError::NotImplemented)),
|
||||||
Self::Clickhouse(pool) => {
|
Self::Clickhouse(pool) => {
|
||||||
metric
|
metric
|
||||||
.load_metrics(merchant_id, publishable_key, granularity, time_range, pool)
|
.load_metrics(merchant_id, granularity, time_range, pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Self::CombinedCkh(_sqlx_pool, ckh_pool) | Self::CombinedSqlx(_sqlx_pool, ckh_pool) => {
|
Self::CombinedCkh(_sqlx_pool, ckh_pool) | Self::CombinedSqlx(_sqlx_pool, ckh_pool) => {
|
||||||
metric
|
metric
|
||||||
.load_metrics(
|
.load_metrics(
|
||||||
merchant_id,
|
merchant_id,
|
||||||
publishable_key,
|
|
||||||
granularity,
|
granularity,
|
||||||
// Since API events are ckh only use ckh here
|
// Since API events are ckh only use ckh here
|
||||||
time_range,
|
time_range,
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use api_models::{
|
|||||||
},
|
},
|
||||||
refunds::RefundStatus,
|
refunds::RefundStatus,
|
||||||
};
|
};
|
||||||
|
use common_enums::{AuthenticationStatus, TransactionStatus};
|
||||||
use common_utils::{
|
use common_utils::{
|
||||||
errors::{CustomResult, ParsingError},
|
errors::{CustomResult, ParsingError},
|
||||||
id_type::{MerchantId, OrganizationId, ProfileId},
|
id_type::{MerchantId, OrganizationId, ProfileId},
|
||||||
@ -502,6 +503,8 @@ impl_to_sql_for_to_string!(
|
|||||||
Currency,
|
Currency,
|
||||||
RefundType,
|
RefundType,
|
||||||
FrmTransactionType,
|
FrmTransactionType,
|
||||||
|
TransactionStatus,
|
||||||
|
AuthenticationStatus,
|
||||||
Flow,
|
Flow,
|
||||||
&String,
|
&String,
|
||||||
&bool,
|
&bool,
|
||||||
|
|||||||
@ -1034,6 +1034,8 @@ impl ToSql<SqlxClient> for AnalyticsCollection {
|
|||||||
Self::Dispute => Ok("dispute".to_string()),
|
Self::Dispute => Ok("dispute".to_string()),
|
||||||
Self::DisputeSessionized => Err(error_stack::report!(ParsingError::UnknownError)
|
Self::DisputeSessionized => Err(error_stack::report!(ParsingError::UnknownError)
|
||||||
.attach_printable("DisputeSessionized table is not implemented for Sqlx"))?,
|
.attach_printable("DisputeSessionized table is not implemented for Sqlx"))?,
|
||||||
|
Self::Authentications => Err(error_stack::report!(ParsingError::UnknownError)
|
||||||
|
.attach_printable("Authentications table is not implemented for Sqlx"))?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@ pub enum AnalyticsCollection {
|
|||||||
PaymentIntentSessionized,
|
PaymentIntentSessionized,
|
||||||
ConnectorEvents,
|
ConnectorEvents,
|
||||||
OutgoingWebhookEvent,
|
OutgoingWebhookEvent,
|
||||||
|
Authentications,
|
||||||
Dispute,
|
Dispute,
|
||||||
DisputeSessionized,
|
DisputeSessionized,
|
||||||
ApiEventsAnalytics,
|
ApiEventsAnalytics,
|
||||||
|
|||||||
@ -5,6 +5,29 @@ use std::{
|
|||||||
|
|
||||||
use super::NameDescription;
|
use super::NameDescription;
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Debug,
|
||||||
|
serde::Serialize,
|
||||||
|
serde::Deserialize,
|
||||||
|
strum::AsRefStr,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Eq,
|
||||||
|
Ord,
|
||||||
|
strum::Display,
|
||||||
|
strum::EnumIter,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
pub enum AuthEventDimensions {
|
||||||
|
#[serde(rename = "authentication_status")]
|
||||||
|
AuthenticationStatus,
|
||||||
|
#[serde(rename = "trans_status")]
|
||||||
|
TransactionStatus,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Debug,
|
Debug,
|
||||||
@ -20,7 +43,7 @@ use super::NameDescription;
|
|||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum AuthEventMetrics {
|
pub enum AuthEventMetrics {
|
||||||
ThreeDsSdkCount,
|
AuthenticationCount,
|
||||||
AuthenticationAttemptCount,
|
AuthenticationAttemptCount,
|
||||||
AuthenticationSuccessCount,
|
AuthenticationSuccessCount,
|
||||||
ChallengeFlowCount,
|
ChallengeFlowCount,
|
||||||
@ -48,7 +71,7 @@ pub enum AuthEventFlows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod metric_behaviour {
|
pub mod metric_behaviour {
|
||||||
pub struct ThreeDsSdkCount;
|
pub struct AuthenticationCount;
|
||||||
pub struct AuthenticationAttemptCount;
|
pub struct AuthenticationAttemptCount;
|
||||||
pub struct AuthenticationSuccessCount;
|
pub struct AuthenticationSuccessCount;
|
||||||
pub struct ChallengeFlowCount;
|
pub struct ChallengeFlowCount;
|
||||||
@ -96,7 +119,7 @@ impl PartialEq for AuthEventMetricsBucketIdentifier {
|
|||||||
|
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct AuthEventMetricsBucketValue {
|
pub struct AuthEventMetricsBucketValue {
|
||||||
pub three_ds_sdk_count: Option<u64>,
|
pub authentication_count: Option<u64>,
|
||||||
pub authentication_attempt_count: Option<u64>,
|
pub authentication_attempt_count: Option<u64>,
|
||||||
pub authentication_success_count: Option<u64>,
|
pub authentication_success_count: Option<u64>,
|
||||||
pub challenge_flow_count: Option<u64>,
|
pub challenge_flow_count: Option<u64>,
|
||||||
|
|||||||
@ -975,7 +975,6 @@ pub mod routes {
|
|||||||
analytics::auth_events::get_metrics(
|
analytics::auth_events::get_metrics(
|
||||||
&state.pool,
|
&state.pool,
|
||||||
auth.merchant_account.get_id(),
|
auth.merchant_account.get_id(),
|
||||||
&auth.merchant_account.publishable_key,
|
|
||||||
req,
|
req,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
Reference in New Issue
Block a user