fix: duplicate entries in total count when filtering by object ID (#8109)

Co-authored-by: Aishwariyaa Anand <aishwariyaa.anand@Aishwariyaa-Anand-C3PGW02T6Y.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Aishwariyaa Anand
2025-05-27 11:40:32 +05:30
committed by GitHub
parent bc4bab935f
commit 5c8394a621

View File

@ -42,27 +42,38 @@ pub async fn list_initial_delivery_attempts(
let events_list_begin_time = let events_list_begin_time =
(now.date() - time::Duration::days(INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS)).midnight(); (now.date() - time::Duration::days(INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS)).midnight();
let mut updated_event_types: HashSet<common_enums::EventType> = HashSet::new(); let (events, total_count) = match constraints {
let events = match constraints {
api_models::webhook_events::EventListConstraintsInternal::ObjectIdFilter { object_id } => { api_models::webhook_events::EventListConstraintsInternal::ObjectIdFilter { object_id } => {
match account { let events = match account {
MerchantAccountOrProfile::MerchantAccount(merchant_account) => store MerchantAccountOrProfile::MerchantAccount(merchant_account) => {
.list_initial_events_by_merchant_id_primary_object_id(key_manager_state, store
.list_initial_events_by_merchant_id_primary_object_id(
key_manager_state,
merchant_account.get_id(), merchant_account.get_id(),
&object_id, &object_id,
&key_store, &key_store,
) )
.await, .await
MerchantAccountOrProfile::Profile(business_profile) => store }
.list_initial_events_by_profile_id_primary_object_id(key_manager_state, MerchantAccountOrProfile::Profile(business_profile) => {
store
.list_initial_events_by_profile_id_primary_object_id(
key_manager_state,
business_profile.get_id(), business_profile.get_id(),
&object_id, &object_id,
&key_store, &key_store,
) )
.await, .await
} }
} }
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to list events with specified constraints")?;
let total_count = i64::try_from(events.len())
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Error while converting from usize to i64")?;
(events, total_count)
}
api_models::webhook_events::EventListConstraintsInternal::GenericFilter { api_models::webhook_events::EventListConstraintsInternal::GenericFilter {
created_after, created_after,
created_before, created_before,
@ -70,7 +81,7 @@ pub async fn list_initial_delivery_attempts(
offset, offset,
event_classes, event_classes,
event_types, event_types,
is_delivered is_delivered,
} => { } => {
let limit = match limit { let limit = match limit {
Some(limit) if limit <= INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_LIMIT => Ok(Some(limit)), Some(limit) if limit <= INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_LIMIT => Ok(Some(limit)),
@ -87,94 +98,100 @@ pub async fn list_initial_delivery_attempts(
}; };
let event_classes = event_classes.unwrap_or(HashSet::new()); let event_classes = event_classes.unwrap_or(HashSet::new());
updated_event_types = event_types.unwrap_or(HashSet::new()); let mut event_types = event_types.unwrap_or(HashSet::new());
if !event_classes.is_empty() { if !event_classes.is_empty() {
updated_event_types = finalize_event_types(event_classes, updated_event_types).await?; event_types = finalize_event_types(event_classes, event_types).await?;
} }
fp_utils::when(!created_after.zip(created_before).map(|(created_after,created_before)| created_after<=created_before).unwrap_or(true), || { fp_utils::when(
!created_after
.zip(created_before)
.map(|(created_after, created_before)| created_after <= created_before)
.unwrap_or(true),
|| {
Err(errors::ApiErrorResponse::InvalidRequestData { message: "The `created_after` timestamp must be an earlier timestamp compared to the `created_before` timestamp".to_string() }) Err(errors::ApiErrorResponse::InvalidRequestData { message: "The `created_after` timestamp must be an earlier timestamp compared to the `created_before` timestamp".to_string() })
})?; },
)?;
let created_after = match created_after { let created_after = match created_after {
Some(created_after) => { Some(created_after) => {
if created_after < events_list_begin_time { if created_after < events_list_begin_time {
Err(errors::ApiErrorResponse::InvalidRequestData { message: format!("`created_after` must be a timestamp within the past {INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS} days.") }) Err(errors::ApiErrorResponse::InvalidRequestData { message: format!("`created_after` must be a timestamp within the past {INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS} days.") })
}else{ } else {
Ok(created_after) Ok(created_after)
} }
}, }
None => Ok(events_list_begin_time) None => Ok(events_list_begin_time),
}?; }?;
let created_before = match created_before{ let created_before = match created_before {
Some(created_before) => { Some(created_before) => {
if created_before < events_list_begin_time{ if created_before < events_list_begin_time {
Err(errors::ApiErrorResponse::InvalidRequestData { message: format!("`created_before` must be a timestamp within the past {INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS} days.") }) Err(errors::ApiErrorResponse::InvalidRequestData { message: format!("`created_before` must be a timestamp within the past {INITIAL_DELIVERY_ATTEMPTS_LIST_MAX_DAYS} days.") })
} } else {
else{
Ok(created_before) Ok(created_before)
} }
}, }
None => Ok(now) None => Ok(now),
}?; }?;
match account { let events = match account {
MerchantAccountOrProfile::MerchantAccount(merchant_account) => store MerchantAccountOrProfile::MerchantAccount(merchant_account) => {
.list_initial_events_by_merchant_id_constraints(key_manager_state, store
.list_initial_events_by_merchant_id_constraints(
key_manager_state,
merchant_account.get_id(), merchant_account.get_id(),
created_after, created_after,
created_before, created_before,
limit, limit,
offset, offset,
updated_event_types.clone(), event_types.clone(),
is_delivered, is_delivered,
&key_store, &key_store,
) )
.await, .await
MerchantAccountOrProfile::Profile(business_profile) => store }
.list_initial_events_by_profile_id_constraints(key_manager_state, MerchantAccountOrProfile::Profile(business_profile) => {
store
.list_initial_events_by_profile_id_constraints(
key_manager_state,
business_profile.get_id(), business_profile.get_id(),
created_after, created_after,
created_before, created_before,
limit, limit,
offset, offset,
updated_event_types.clone(), event_types.clone(),
is_delivered, is_delivered,
&key_store, &key_store,
) )
.await, .await
}
} }
} }
.change_context(errors::ApiErrorResponse::InternalServerError) .change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to list events with specified constraints")?; .attach_printable("Failed to list events with specified constraints")?;
let events = events
.into_iter()
.map(api::webhook_events::EventListItemResponse::try_from)
.collect::<Result<Vec<_>, _>>()?;
let created_after = api_constraints
.created_after
.unwrap_or(events_list_begin_time);
let created_before = api_constraints.created_before.unwrap_or(now);
let is_delivered = api_constraints.is_delivered;
let total_count = store let total_count = store
.count_initial_events_by_constraints( .count_initial_events_by_constraints(
&merchant_id, &merchant_id,
profile_id, profile_id,
created_after, created_after,
created_before, created_before,
updated_event_types, event_types,
is_delivered, is_delivered,
) )
.await .await
.change_context(errors::ApiErrorResponse::InternalServerError) .change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to get total events count")?; .attach_printable("Failed to get total events count")?;
(events, total_count)
}
};
let events = events
.into_iter()
.map(api::webhook_events::EventListItemResponse::try_from)
.collect::<Result<Vec<_>, _>>()?;
Ok(ApplicationResponse::Json( Ok(ApplicationResponse::Json(
api::webhook_events::TotalEventsResponse::new(total_count, events), api::webhook_events::TotalEventsResponse::new(total_count, events),
)) ))