Repository: juspay/hyperswitch
File: crates/router/src/core/unified_connector_service.rs (Rust)

Code before:
        payments::{
            helpers::{
                is_ucs_enabled, should_execute_based_on_rollout, MerchantConnectorAccountType,
            },
            OperationSessionGetters, OperationSessionSetters,
        },
        utils::get_flow_name,
    },
    events::connector_api_logs::ConnectorEvent,
    routes::SessionState,
    types::transformers::ForeignTryFrom,
};

pub mod transformers;

// Re-export webhook transformer types for easier access
pub use transformers::WebhookTransformData;

/// Type alias for the complex return type used by unified connector service response handlers
type UnifiedConnectorServiceResult = CustomResult<
    (
        Option<AttemptStatus>,
        Result<PaymentsResponseData, ErrorResponse>,
        u16,
    ),
    UnifiedConnectorServiceError,
>;

/// Generic version of should_call_unified_connector_service that works with any type
/// implementing OperationSessionGetters trait
pub async fn should_call_unified_connector_service<F: Clone, T, D>(
    state: &SessionState,
    merchant_context: &MerchantContext,
    router_data: &RouterData<F, T, PaymentsResponseData>,
    payment_data: Option<&D>,
) -> RouterResult<bool>
where
    D: OperationSessionGetters<F>,
{
    // Check basic UCS availability first
    if state.grpc_client.unified_connector_service_client.is_none() {
        router_env::logger::debug!(
            "Unified Connector Service client is not available, skipping UCS decision"
        );
        return Ok(false);
    }

    let ucs_config_key = consts::UCS_ENABLED;
    if !is_ucs_enabled(state, ucs_config_key).await {
        router_env::logger::debug!(
            "Unified Connector Service is not enabled, skipping UCS decision"

Review comment (suggestion):
Since we know that Attempt status will only be returned during Ok response put it as a part of inner result. So In case of Err, it will not be retuned. And there is no need to convert from grpc::PaymentStatus to` Option < AttemptStatus>.`


This needs to be handles appropriately in the response handler function.
```suggestion
type UnifiedConnectorServiceResult = CustomResult<
    (
        Result<(PaymentsResponseData, AttemptStatus), ErrorResponse>,
        u16,
    ),
    UnifiedConnectorServiceError,
>;
```

Code after:
        payments::{
            helpers::{
                is_ucs_enabled, should_execute_based_on_rollout, MerchantConnectorAccountType,
            },
            OperationSessionGetters, OperationSessionSetters,
        },
        utils::get_flow_name,
    },
    events::connector_api_logs::ConnectorEvent,
    routes::SessionState,
    types::transformers::ForeignTryFrom,
};

pub mod transformers;

// Re-export webhook transformer types for easier access
pub use transformers::WebhookTransformData;

/// Type alias for return type used by unified connector service response handlers
type UnifiedConnectorServiceResult = CustomResult<
    (
        Result<(PaymentsResponseData, AttemptStatus), ErrorResponse>,
        u16,
    ),
    UnifiedConnectorServiceError,
>;

/// Generic version of should_call_unified_connector_service that works with any type
/// implementing OperationSessionGetters trait
pub async fn should_call_unified_connector_service<F: Clone, T, D>(
    state: &SessionState,
    merchant_context: &MerchantContext,
    router_data: &RouterData<F, T, PaymentsResponseData>,
    payment_data: Option<&D>,
) -> RouterResult<bool>
where
    D: OperationSessionGetters<F>,
{
    // Check basic UCS availability first
    if state.grpc_client.unified_connector_service_client.is_none() {
        router_env::logger::debug!(
            "Unified Connector Service client is not available, skipping UCS decision"
        );
        return Ok(false);
    }

    let ucs_config_key = consts::UCS_ENABLED;
    if !is_ucs_enabled(state, ucs_config_key).await {
        router_env::logger::debug!(
            "Unified Connector Service is not enabled, skipping UCS decision"
        );