ronantakizawa/codereview-bench huggingface dataset:
Repository: juspay/hyperswitch
File: crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs (Rust)

Code before:

impl From<String> for utils::ErrorCodeAndMessage {
    fn from(error: String) -> Self {
        Self {
            error_code: error.clone(),
            error_message: error,
        }
    }
}

fn convert_to_additional_payment_method_connector_response(
    source: Option<&Source>,
) -> Option<AdditionalPaymentMethodConnectorResponse> {
    match source {
        None => None,
        Some(code) => {
            let payment_checks = serde_json::json!({
                "avs_result": code.avs_check,
                "card_validation_result": code.cvv_check,
            });
            Some(AdditionalPaymentMethodConnectorResponse::Card {
                authentication_data: None,
                payment_checks: Some(payment_checks),
                card_network: None,
                domestic_network: None,
            })
        }
    }
}


Review comment (security):
```suggestion
fn convert_to_additional_payment_method_connector_response(
    source: Option<&Source>,
) -> Option<AdditionalPaymentMethodConnectorResponse> {
    source.map(|code| {
        let payment_checks = serde_json::json!({
            "avs_result": code.avs_check,
            "card_validation_result": code.cvv_check,
        });
        AdditionalPaymentMethodConnectorResponse::Card {
            authentication_data: None,
            payment_checks: Some(payment_checks),
            card_network: None,
            domestic_network: None,
        }
    })
}
```

Code after:

impl From<String> for utils::ErrorCodeAndMessage {
    fn from(error: String) -> Self {
        Self {
            error_code: error.clone(),
            error_message: error,
        }
    }
}

fn convert_to_additional_payment_method_connector_response(
    source: Option<&Source>,
) -> Option<AdditionalPaymentMethodConnectorResponse> {
    source.map(|code| {
        let payment_checks = serde_json::json!({
            "avs_result": code.avs_check,
            "card_validation_result": code.cvv_check,
        });
        AdditionalPaymentMethodConnectorResponse::Card {
            authentication_data: None,
            payment_checks: Some(payment_checks),
            card_network: None,
            domestic_network: None,
        }
    })
}
Repository: juspay/hyperswitch
File: crates/hyperswitch_domain_models/src/payments/payment_intent.rs (Rust)

Code before:
use common_types::primitive_wrappers::EnablePartialAuthorizationBool;
#[cfg(feature = "v1")]
use common_utils::consts::PAYMENTS_LIST_MAX_LIMIT_V2;
#[cfg(feature = "v2")]
use common_utils::errors::ParsingError;
#[cfg(feature = "v2")]
use common_utils::ext_traits::{Encode, ValueExt};
use common_utils::{
    consts::PAYMENTS_LIST_MAX_LIMIT_V1,
    crypto::Encryptable,
    encryption::Encryption,
    errors::{CustomResult, ValidationError},
    id_type,
    pii::{self, Email},
    type_name,
    types::{
        keymanager::{self, KeyManagerState, ToEncryptable},
        CreatedBy, MinorUnit,
    },
};
use diesel_models::{
    PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew,
};
use error_stack::ResultExt;
#[cfg(feature = "v2")]
use masking::ExposeInterface;

Review comment (suggestion):
```suggestion
use common_types::primitive_wrappers;
```

Code after:
use common_types::primitive_wrappers;
#[cfg(feature = "v1")]
use common_utils::consts::PAYMENTS_LIST_MAX_LIMIT_V2;
#[cfg(feature = "v2")]
use common_utils::errors::ParsingError;
#[cfg(feature = "v2")]
use common_utils::ext_traits::{Encode, ValueExt};
use common_utils::{
    consts::PAYMENTS_LIST_MAX_LIMIT_V1,
    crypto::Encryptable,
    encryption::Encryption,
    errors::{CustomResult, ValidationError},
    id_type,
    pii::{self, Email},
    type_name,
    types::{
        keymanager::{self, KeyManagerState, ToEncryptable},
        CreatedBy, MinorUnit,
    },
};
use diesel_models::{
    PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew,
};
use error_stack::ResultExt;
#[cfg(feature = "v2")]
use masking::ExposeInterface;
Repository: juspay/hyperswitch
File: crates/hyperswitch_domain_models/src/merchant_context.rs (Rust)

Code before:
use common_utils::id_type::ProfileId;

pub use crate::{
    business_profile::Profile, merchant_account::MerchantAccount,
    merchant_key_store::MerchantKeyStore,
};

/// `MerchantContext` represents the authentication and operational context for a merchant.
///
/// This enum encapsulates the merchant's account information and cryptographic keys
/// needed for secure operations. Currently supports only normal merchant operations,
/// but the enum structure allows for future expansion to different merchant types for example a
/// **platform** context.
#[derive(Clone, Debug)]
pub enum MerchantContext<A = ()> {
    /// Represents a normal operation merchant context.
    NormalMerchant(Box<Context>),
    /// Represents a normal operation merchant context with additional accounts information.
    NormalMerchantWithAddOns(Box<ContextWithAddOns<A>>),
}

pub type MerchantContextWithProfile = MerchantContext<ProfileId>;

/// `Context` holds the merchant account details and cryptographic key store.
#[derive(Clone, Debug)]
pub struct Context(pub MerchantAccount, pub MerchantKeyStore);

impl Context {
    pub fn new(merchant_account: MerchantAccount, key_store: MerchantKeyStore) -> Self {

Review comment (suggestion):
```suggestion
    business_profile, merchant_account,
```

Code after:
pub use crate::{merchant_account::MerchantAccount, merchant_key_store::MerchantKeyStore};

/// `MerchantContext` represents the authentication and operational context for a merchant.
///
/// This enum encapsulates the merchant's account information and cryptographic keys
/// needed for secure operations. Currently supports only normal merchant operations,
/// but the enum structure allows for future expansion to different merchant types for example a
/// **platform** context.
#[derive(Clone, Debug)]
pub enum MerchantContext {
    /// Represents a normal operation merchant context.
    NormalMerchant(Box<Context>),
}
/// `Context` holds the merchant account details and cryptographic key store.
#[derive(Clone, Debug)]
pub struct Context(pub MerchantAccount, pub MerchantKeyStore);

impl MerchantContext {
    pub fn get_merchant_account(&self) -> &MerchantAccount {
        match self {
            Self::NormalMerchant(merchant_account) => &merchant_account.0,
        }
    }

    pub fn get_merchant_key_store(&self) -> &MerchantKeyStore {
        match self {
            Self::NormalMerchant(merchant_account) => &merchant_account.1,
        }
    }
Repository: juspay/hyperswitch
File: crates/api_models/src/events/customer.rs (Rust)

Code before:
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}

impl ApiEventMetric for CustomerListResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        None
    }
}


Review comment (suggestion):
Since we don't need new response type i don't think we need this. Please check and remove.

I don't think we are returning this response anywhere, we are returning existing response.

Code after:
use common_utils::events::{ApiEventMetric, ApiEventsType};

use crate::customers::{
    CustomerDeleteResponse, CustomerRequest, CustomerResponse, CustomerUpdateRequestInternal,
};

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerDeleteResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerDeleteResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerRequest {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        self.get_merchant_reference_id()
            .clone()
            .map(|cid| ApiEventsType::Customer { customer_id: cid })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerRequest {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer { customer_id: None })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        self.get_merchant_reference_id()
            .clone()
            .map(|cid| ApiEventsType::Customer { customer_id: cid })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}
Repository: juspay/hyperswitch
File: crates/hyperswitch_domain_models/src/customer.rs (Rust)

Code before:
                tax_registration_id: None,
            },
            CustomerUpdate::UpdateDefaultPaymentMethod {
                default_payment_method_id,
            } => Self {
                default_payment_method_id,
                modified_at: date_time::now(),
                name: None,
                email: None,
                phone: None,
                description: None,
                phone_country_code: None,
                metadata: None,
                connector_customer: None,
                updated_by: None,
                address_id: None,
                tax_registration_id: None,
            },
        }
    }
}

pub struct CustomerListConstraints {
    pub limit: u16,
    pub offset: Option<u32>,
    pub customer_id: Option<String>,
}

impl From<CustomerListConstraints> for query::CustomerListConstraints {
    fn from(value: CustomerListConstraints) -> Self {
        Self {
            limit: i64::from(value.limit),
            offset: value.offset.map(i64::from),
            customer_id: value.customer_id.filter(|s| !s.trim().is_empty()),
        }
    }
}

#[async_trait::async_trait]
pub trait CustomerInterface
where
    Customer: behaviour::Conversion<
        DstType = storage_types::Customer,
        NewDstType = storage_types::CustomerNew,
    >,
{
    type Error;
    #[cfg(feature = "v1")]
    async fn delete_customer_by_customer_id_merchant_id(
        &self,
        customer_id: &id_type::CustomerId,

Review comment (suggestion):
```suggestion
    pub customer_id: Option<id_type::CustomerId>,
```

Code after:
                tax_registration_id: None,
            },
            CustomerUpdate::UpdateDefaultPaymentMethod {
                default_payment_method_id,
            } => Self {
                default_payment_method_id,
                modified_at: date_time::now(),
                name: None,
                email: None,
                phone: None,
                description: None,
                phone_country_code: None,
                metadata: None,
                connector_customer: None,
                updated_by: None,
                address_id: None,
                tax_registration_id: None,
            },
        }
    }
}

pub struct CustomerListConstraints {
    pub limit: u16,
    pub offset: Option<u32>,
    pub customer_id: Option<id_type::CustomerId>,
}

impl From<CustomerListConstraints> for query::CustomerListConstraints {
    fn from(value: CustomerListConstraints) -> Self {
        Self {
            limit: i64::from(value.limit),
            offset: value.offset.map(i64::from),
            customer_id: value.customer_id,
        }
    }
}

#[async_trait::async_trait]
pub trait CustomerInterface
where
    Customer: behaviour::Conversion<
        DstType = storage_types::Customer,
        NewDstType = storage_types::CustomerNew,
    >,
{
    type Error;
    #[cfg(feature = "v1")]
    async fn delete_customer_by_customer_id_merchant_id(
        &self,
        customer_id: &id_type::CustomerId,
Repository: juspay/hyperswitch
File: crates/router/src/core/routing/helpers.rs (Rust)

Code before:
    Ok(())
}

pub async fn redact_cgraph_cache(
    state: &SessionState,
    merchant_id: &id_type::MerchantId,
    profile_id: &id_type::ProfileId,
) -> RouterResult<()> {
    let cgraph_payouts_key = format!(
        "cgraph_po_{}_{}",
        merchant_id.get_string_repr(),
        profile_id.get_string_repr(),
    );

    let cgraph_payments_key = format!(
        "cgraph_{}_{}",
        merchant_id.get_string_repr(),
        profile_id.get_string_repr(),
    );

    let config_payouts_key = cache::CacheKind::CGraph(cgraph_payouts_key.clone().into());
    cache::redact_from_redis_and_publish(
        state.store.get_cache_store().as_ref(),
        [config_payouts_key],
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable("Failed to invalidate the cgraph cache")?;

    let config_payments_key = cache::CacheKind::CGraph(cgraph_payments_key.clone().into());
    cache::redact_from_redis_and_publish(
        state.store.get_cache_store().as_ref(),
        [config_payments_key],
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable("Failed to invalidate the cgraph cache")?;

    Ok(())
}


Review comment (suggestion):
I believe we can directly use the `redact_from_redis_and_publish` function wherever required instead of creating a new one.

Code after:
    Ok(())
}

pub async fn redact_cgraph_cache(
    state: &SessionState,
    merchant_id: &id_type::MerchantId,
    profile_id: &id_type::ProfileId,
) -> RouterResult<()> {
    let cgraph_payouts_key = format!(
        "cgraph_po_{}_{}",
        merchant_id.get_string_repr(),
        profile_id.get_string_repr(),
    );

    let cgraph_payments_key = format!(
        "cgraph_{}_{}",
        merchant_id.get_string_repr(),
        profile_id.get_string_repr(),
    );

    let config_payouts_key = cache::CacheKind::CGraph(cgraph_payouts_key.clone().into());
    let config_payments_key = cache::CacheKind::CGraph(cgraph_payments_key.clone().into());
    cache::redact_from_redis_and_publish(
        state.store.get_cache_store().as_ref(),
        [config_payouts_key, config_payments_key],
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable("Failed to invalidate the cgraph cache")?;

    Ok(())
}
Repository: juspay/hyperswitch
File: crates/common_enums/src/enums.rs (Rust)

Code before:
#[strum(serialize_all = "snake_case")]
pub enum ExternalVaultEnabled {
    Enable,
    #[default]
    Skip,
}

#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "UPPERCASE")]
pub enum GooglePayCardFundingSource {
    Credit,
    Debit,
    Prepaid,
    #[serde(other)]
    Unknown,
}

impl From<IntentStatus> for InvoiceStatus {
    fn from(value: IntentStatus) -> Self {
        match value {
            IntentStatus::Succeeded => Self::InvoicePaid,
            IntentStatus::Processing
            | IntentStatus::RequiresCustomerAction
            | IntentStatus::RequiresConfirmation
            | IntentStatus::RequiresPaymentMethod => Self::PaymentPending,
            _ => Self::PaymentFailed,
        }
    }
}


Review comment (bug):
``` suggestion
          IntentStatus::Failed   => Self::PaymentFailed,
```
Add all the specific fields here and map appropriately Eg: Cancelled -> PaymentCanceled, RequiresCapture -> InvoicePaid

Code after:
#[strum(serialize_all = "snake_case")]
pub enum ExternalVaultEnabled {
    Enable,
    #[default]
    Skip,
}

#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "UPPERCASE")]
pub enum GooglePayCardFundingSource {
    Credit,
    Debit,
    Prepaid,
    #[serde(other)]
    Unknown,
}

impl From<IntentStatus> for InvoiceStatus {
    fn from(value: IntentStatus) -> Self {
        match value {
            IntentStatus::Succeeded => Self::InvoicePaid,
            IntentStatus::RequiresCapture
            | IntentStatus::PartiallyCaptured
            | IntentStatus::PartiallyCapturedAndCapturable
            | IntentStatus::PartiallyAuthorizedAndRequiresCapture
            | IntentStatus::Processing
            | IntentStatus::RequiresCustomerAction
            | IntentStatus::RequiresConfirmation
            | IntentStatus::RequiresPaymentMethod => Self::PaymentPending,
            IntentStatus::RequiresMerchantAction => Self::ManualReview,
            IntentStatus::Cancelled | IntentStatus::CancelledPostCapture => Self::PaymentCanceled,
            IntentStatus::Expired => Self::PaymentPendingTimeout,
            IntentStatus::Failed | IntentStatus::Conflicted => Self::PaymentFailed,
        }
    }
}
Repository: juspay/hyperswitch
File: crates/api_models/src/events/customer.rs (Rust)

Code before:
            customer_id: Some(self.id.clone()),
        })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}

impl ApiEventMetric for CustomerListRequestWithConstraints {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        None
    }
}

impl ApiEventMetric for CustomerListResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        None
    }
}


Review comment (suggestion):
We can follow the pattern used in other impls here. This is used for tracking api_events which are stored in clickhouse. We can construct ApiEventsType::Customer here.

Code after:
            customer_id: Some(self.id.clone()),
        })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerUpdateRequestInternal {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: Some(self.id.clone()),
        })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerListRequestWithConstraints {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer {
            customer_id: self.customer_id.clone()?,
        })
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerListRequestWithConstraints {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::Customer { customer_id: None })
    }
}

#[cfg(feature = "v1")]
impl ApiEventMetric for CustomerListResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::ResourceListAPI)
    }
}

#[cfg(feature = "v2")]
impl ApiEventMetric for CustomerListResponse {
    fn get_api_event_type(&self) -> Option<ApiEventsType> {
        Some(ApiEventsType::ResourceListAPI)
    }
Repository: juspay/hyperswitch
File: crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs (Rust)

Code before:
                            },
                        }),
                    })
                    .ok_or(errors::ConnectorError::MissingRequiredField {
                        field_name: "order_details",
                    })?,
            ),
            _ => None,
        };

        Ok(Self {
            request_id: Uuid::new_v4().to_string(),
            amount,
            currency,
            merchant_order_id: item.router_data.connector_request_reference_id.clone(),
            referrer_data,
            order,
        })
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AirwallexOrderResponse {
    pub status: AirwallexPaymentStatus,
    pub id: String,
    pub amount: Option<f32>,
    pub payment_consent_id: Option<Secret<String>>,
    pub next_action: Option<AirwallexPaymentsNextAction>,
}

impl TryFrom<CreateOrderResponseRouterData<AirwallexOrderResponse>>
    for types::CreateOrderRouterData
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: CreateOrderResponseRouterData<AirwallexOrderResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            reference_id: Some(item.response.id.clone()),
            response: Ok(PaymentsResponseData::PaymentsCreateOrderResponse {
                order_id: item.response.id.clone(),
            }),
            ..item.data
        })
    }
}

#[derive(Debug, Serialize)]
pub struct AirwallexRouterData<T> {
    pub amount: StringMajorUnit,
    pub router_data: T,

Review comment (suggestion):
```suggestion
    pub amount: Option<StringMajorUnit>,
```

Code after:
                            },
                        }),
                    })
                    .ok_or(errors::ConnectorError::MissingRequiredField {
                        field_name: "order_details",
                    })?,
            ),
            _ => None,
        };

        Ok(Self {
            request_id: Uuid::new_v4().to_string(),
            amount,
            currency,
            merchant_order_id: item.router_data.connector_request_reference_id.clone(),
            referrer_data,
            order,
        })
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AirwallexOrderResponse {
    pub status: AirwallexPaymentStatus,
    pub id: String,
    pub payment_consent_id: Option<Secret<String>>,
    pub next_action: Option<AirwallexPaymentsNextAction>,
}

impl TryFrom<CreateOrderResponseRouterData<AirwallexOrderResponse>>
    for types::CreateOrderRouterData
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: CreateOrderResponseRouterData<AirwallexOrderResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(PaymentsResponseData::PaymentsCreateOrderResponse {
                order_id: item.response.id.clone(),
            }),
            ..item.data
        })
    }
}

#[derive(Debug, Serialize)]
pub struct AirwallexRouterData<T> {
    pub amount: StringMajorUnit,
    pub router_data: T,
}