Bug: refactor(success_based): add support for exploration




diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json
index 039981f661b..fbabc864672 100644
--- a/api-reference-v2/openapi_spec.json
+++ b/api-reference-v2/openapi_spec.json
@@ -23374,9 +23374,13 @@
           },
           "specificity_level": {
             "$ref": "#/components/schemas/SuccessRateSpecificityLevel"
+          },
+          "exploration_percent": {
+            "type": "number",
+            "format": "double",
+            "nullable": true
           }
-        },
-        "additionalProperties": false
+        }
       },
       "SuccessRateSpecificityLevel": {
         "type": "string",
diff --git a/crates/api_models/src/open_router.rs b/crates/api_models/src/open_router.rs
index f15d9cbcfeb..cfcb45ef97b 100644
--- a/crates/api_models/src/open_router.rs
+++ b/crates/api_models/src/open_router.rs
@@ -62,6 +62,7 @@ pub struct PaymentInfo {
 pub struct DecidedGateway {
     pub gateway_priority_map: Option<HashMap<String, f64>>,
     pub debit_routing_output: Option<DebitRoutingOutput>,
+    pub routing_approach: String,
 }
 
 #[derive(Debug, Serialize, Deserialize, PartialEq)]
diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs
index a15b135ac1f..7633f44156e 100644
--- a/crates/api_models/src/routing.rs
+++ b/crates/api_models/src/routing.rs
@@ -960,6 +960,7 @@ impl Default for SuccessBasedRoutingConfig {
                     max_total_count: Some(5),
                 }),
                 specificity_level: SuccessRateSpecificityLevel::default(),
+                exploration_percent: Some(20.0),
             }),
             decision_engine_configs: None,
         }
@@ -980,7 +981,6 @@ pub enum DynamicRoutingConfigParams {
 }
 
 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
-#[serde(deny_unknown_fields)]
 pub struct SuccessBasedRoutingConfigBody {
     pub min_aggregates_size: Option<u32>,
     pub default_success_rate: Option<f64>,
@@ -988,6 +988,7 @@ pub struct SuccessBasedRoutingConfigBody {
     pub current_block_threshold: Option<CurrentBlockThreshold>,
     #[serde(default)]
     pub specificity_level: SuccessRateSpecificityLevel,
+    pub exploration_percent: Option<f64>,
 }
 
 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
@@ -1113,7 +1114,10 @@ impl SuccessBasedRoutingConfigBody {
                 .as_mut()
                 .map(|threshold| threshold.update(current_block_threshold));
         }
-        self.specificity_level = new.specificity_level
+        self.specificity_level = new.specificity_level;
+        if let Some(exploration_percent) = new.exploration_percent {
+            self.exploration_percent = Some(exploration_percent);
+        }
     }
 }
 
diff --git a/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs b/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
index 278a2b50d15..b63f435327e 100644
--- a/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
+++ b/crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs
@@ -290,6 +290,7 @@ impl ForeignTryFrom<SuccessBasedRoutingConfigBody> for CalSuccessRateConfig {
                 SuccessRateSpecificityLevel::Merchant => Some(ProtoSpecificityLevel::Entity.into()),
                 SuccessRateSpecificityLevel::Global => Some(ProtoSpecificityLevel::Global.into()),
             },
+            exploration_percent: config.exploration_percent,
         })
     }
 }
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index b4ac7d4421d..86925cff09f 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -1776,10 +1776,7 @@ pub async fn perform_decide_gateway_call_with_open_router(
                 ))?;
 
             if let Some(gateway_priority_map) = decided_gateway.gateway_priority_map {
-                logger::debug!(
-                    "open_router decide_gateway call response: {:?}",
-                    gateway_priority_map
-                );
+                logger::debug!(gateway_priority_map=?gateway_priority_map, routing_approach=decided_gateway.routing_approach, "open_router decide_gateway call response");
                 routable_connectors.sort_by(|connector_choice_a, connector_choice_b| {
                     let connector_choice_a_score = gateway_priority_map
                         .get(&connector_choice_a.to_string())
diff --git a/proto/success_rate.proto b/proto/success_rate.proto
index 17d566af356..efdd439cac9 100644
--- a/proto/success_rate.proto
+++ b/proto/success_rate.proto
@@ -23,6 +23,7 @@ message CalSuccessRateConfig {
     uint32 min_aggregates_size = 1;
     double default_success_rate = 2;
     optional SuccessRateSpecificityLevel specificity_level = 3;
+    optional double exploration_percent = 4;
 }
 
 enum SuccessRateSpecificityLevel {
@@ -32,6 +33,12 @@ enum SuccessRateSpecificityLevel {
 
 message CalSuccessRateResponse {
     repeated LabelWithScore labels_with_score = 1;
+    RoutingApproach routing_approach = 2;
+}
+
+enum RoutingApproach {
+    EXPLORATION = 0;
+    EXPLOITATION = 1;
 }
 
 message LabelWithScore {

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This pull request introduces a new feature to support an "exploration percentage" parameter in success-based routing configurations and adds a "RoutingApproach" enum to define routing strategies. These changes span multiple files, including API specifications, Rust models, and protocol buffer definitions, ensuring end-to-end support for the new functionality.

### New Feature: Exploration Percentage in Routing Configurations
* Added `exploration_percent` parameter to the `SuccessBasedRoutingConfig` struct in Rust models (`crates/api_models/src/routing.rs`) and updated its default implementation. [[1]](diffhunk://#diff-6eb6e93a94555e904f304999acc96ab6125769971da9ec3dcbb30d5912b4fc45R963) [[2]](diffhunk://#diff-6eb6e93a94555e904f304999acc96ab6125769971da9ec3dcbb30d5912b4fc45R992)
* Modified the `update` method in `SuccessBasedRoutingConfigBody` to handle updates to the `exploration_percent` field.
* Updated the gRPC client (`crates/external_services/src/grpc_client/dynamic_routing/success_rate_client.rs`) to include the `exploration_percent` field in the `CalSuccessRateConfig` mapping.
* Enhanced the protocol buffer definition (`proto/success_rate.proto`) to include `exploration_percent` as an optional field in the `CalSuccessRateConfig` message.

### New Enum: Routing Approach
* Introduced a `RoutingApproach` enum with values `EXPLORATION` and `EXPLOITATION` in the protocol buffer definition (`proto/success_rate.proto`) and added it to the `CalSuccessRateResponse` message.
* Updated the OpenAPI specification (`api-reference/hyperswitch_intelligent_router_open_api_spec.yml`) to include the `RoutingApproach` type and its usage in API responses.

### API Specification Enhancements
* Added `exploration_percent` to the API's routing configuration schema in the OpenAPI spec.

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
1. Toggle success based routing for a profile, Check the business profile table in DB, get the routing_algorithm_id active for that profile and check in routing_algorithm table. it should have exploration set to 20.0

```
curl --location --request POST 'http://localhost:8080/account/merchant_1747851996/business_profile/pro_Rbh3PEV8EITILLoKDC6N/dynamic_routing/success_based/toggle?enable=dynamic_connector_selection' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: xyz' \
--data ''
```

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
