Bug: [FEATURE] Add Cell ID in config



### Feature Description

Add global cell id information in config for v2

### Possible Implementation

Will need to add in settings

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/config/config.example.toml b/config/config.example.toml
index 1f32481fec7..cf6703f43d4 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -734,6 +734,9 @@ connector_list = ""
 [recipient_emails]
 recon = "test@example.com"
 
+[cell_information]
+id = "12345" # Default CellID for Global Cell Information
+
 [network_tokenization_supported_card_networks]
 card_networks = "Visa, AmericanExpress, Mastercard" # Supported card networks for network tokenization
 
diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml
index 319cdafed1d..db43cac979b 100644
--- a/config/deployments/env_specific.toml
+++ b/config/deployments/env_specific.toml
@@ -302,6 +302,9 @@ public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "p
 [user_auth_methods]
 encryption_key = "user_auth_table_encryption_key" # Encryption key used for encrypting data in user_authentication_methods table
 
+[cell_information]
+id = "12345" # Default CellID for Global Cell Information
+
 [network_tokenization_service] # Network Tokenization Service Configuration
 generate_token_url= ""        # base url to generate token
 fetch_token_url= ""           # base url to fetch token
diff --git a/config/development.toml b/config/development.toml
index 6e56d5bb14d..29beed992f6 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -735,6 +735,9 @@ encryption_key = "A8EF32E029BC3342E54BF2E172A4D7AA43E8EF9D2C3A624A9F04E2EF79DC69
 [locker_based_open_banking_connectors]
 connector_list = ""
 
+[cell_information]
+id = "12345"
+
 [network_tokenization_supported_card_networks]
 card_networks = "Visa, AmericanExpress, Mastercard"
 
diff --git a/config/docker_compose.toml b/config/docker_compose.toml
index 15038da0125..77a735aa757 100644
--- a/config/docker_compose.toml
+++ b/config/docker_compose.toml
@@ -137,8 +137,8 @@ ebanx.base_url = "https://sandbox.ebanxpay.com/"
 fiserv.base_url = "https://cert.api.fiservapps.com/"
 fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox"
 fiuu.base_url = "https://sandbox.merchant.razer.com/"
-fiuu.secondary_base_url="https://sandbox.merchant.razer.com/"
-fiuu.third_base_url="https://api.merchant.razer.com/"
+fiuu.secondary_base_url = "https://sandbox.merchant.razer.com/"
+fiuu.third_base_url = "https://api.merchant.razer.com/"
 forte.base_url = "https://sandbox.forte.net/api/v3"
 globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/"
 globepay.base_url = "https://pay.globepay.co/"
@@ -380,7 +380,7 @@ open_banking_uk = { country = "DE,GB,AT,BE,CY,EE,ES,FI,FR,GR,HR,IE,IT,LT,LU,LV,M
 upi_collect = { country = "IN", currency = "INR" }
 
 [pm_filters.plaid]
-open_banking_pis = {currency = "EUR,GBP"}
+open_banking_pis = { currency = "EUR,GBP" }
 
 [pm_filters.zen]
 credit = { not_available_flows = { capture_method = "manual" } }
@@ -552,7 +552,7 @@ sdk_eligible_payment_methods = "card"
 
 [multitenancy]
 enabled = false
-global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default"}
+global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
 
 [multitenancy.tenants]
 public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" }
@@ -592,6 +592,9 @@ ach = { country = "US", currency = "USD" }
 [locker_based_open_banking_connectors]
 connector_list = ""
 
+[cell_information]
+id = "12345"
+
 [network_tokenization_supported_card_networks]
 card_networks = "Visa, AmericanExpress, Mastercard"
 
diff --git a/crates/common_utils/src/id_type/global_id.rs b/crates/common_utils/src/id_type/global_id.rs
index 5ed23a177b6..c0b6384abc6 100644
--- a/crates/common_utils/src/id_type/global_id.rs
+++ b/crates/common_utils/src/id_type/global_id.rs
@@ -63,27 +63,29 @@ impl From<AlphaNumericIdError> for CellIdError {
 
 impl CellId {
     /// Create a new cell id from a string
-    fn from_str(cell_id_string: &str) -> Result<Self, CellIdError> {
-        let trimmed_input_string = cell_id_string.trim().to_string();
+    pub fn from_str(cell_id_string: impl AsRef<str>) -> Result<Self, CellIdError> {
+        let trimmed_input_string = cell_id_string.as_ref().trim().to_string();
         let alphanumeric_id = AlphaNumericId::from(trimmed_input_string.into())?;
         let length_id = LengthId::from_alphanumeric_id(alphanumeric_id)?;
         Ok(Self(length_id))
     }
 
-    pub fn from_string(input_string: String) -> error_stack::Result<Self, errors::ValidationError> {
-        Self::from_str(&input_string).change_context(
-            errors::ValidationError::IncorrectValueProvided {
-                field_name: "cell_id",
-            },
-        )
-    }
-
     /// Get the string representation of the cell id
     fn get_string_repr(&self) -> &str {
         &self.0 .0 .0
     }
 }
 
+impl<'de> serde::Deserialize<'de> for CellId {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::Deserializer<'de>,
+    {
+        let deserialized_string = String::deserialize(deserializer)?;
+        Self::from_str(deserialized_string.as_str()).map_err(serde::de::Error::custom)
+    }
+}
+
 /// Error generated from violation of constraints for MerchantReferenceId
 #[derive(Debug, Error, PartialEq, Eq)]
 pub(crate) enum GlobalIdError {
diff --git a/crates/common_utils/src/id_type/global_id/payment_methods.rs b/crates/common_utils/src/id_type/global_id/payment_methods.rs
index 5ccb774f6ea..3929efd09b5 100644
--- a/crates/common_utils/src/id_type/global_id/payment_methods.rs
+++ b/crates/common_utils/src/id_type/global_id/payment_methods.rs
@@ -28,8 +28,10 @@ pub enum GlobalPaymentMethodIdError {
 
 impl GlobalPaymentMethodId {
     /// Create a new GlobalPaymentMethodId from celll id information
-    pub fn generate(cell_id: &str) -> error_stack::Result<Self, errors::ValidationError> {
-        let cell_id = CellId::from_string(cell_id.to_string())?;
+    pub fn generate(cell_id: &str) -> error_stack::Result<Self, GlobalPaymentMethodIdError> {
+        let cell_id = CellId::from_str(cell_id)
+            .change_context(GlobalPaymentMethodIdError::ConstructionError)
+            .attach_printable("Failed to construct CellId from str")?;
         let global_id = GlobalId::generate(cell_id, GlobalEntity::PaymentMethod);
         Ok(Self(global_id))
     }
diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml
index 442561c2ca3..83d159f6d29 100644
--- a/crates/router/Cargo.toml
+++ b/crates/router/Cargo.toml
@@ -33,7 +33,7 @@ payouts = ["api_models/payouts", "common_enums/payouts", "hyperswitch_connectors
 payout_retry = ["payouts"]
 recon = ["email", "api_models/recon"]
 retry = []
-v2 = ["customer_v2", "payment_methods_v2", "payment_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2"]
+v2 = ["customer_v2", "payment_methods_v2", "payment_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2"]
 v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1"]
 customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"]
 payment_v2 = ["api_models/payment_v2", "diesel_models/payment_v2", "hyperswitch_domain_models/payment_v2", "storage_impl/payment_v2"]
diff --git a/crates/router/src/configs/secrets_transformers.rs b/crates/router/src/configs/secrets_transformers.rs
index 8c893b88319..e1b68efc446 100644
--- a/crates/router/src/configs/secrets_transformers.rs
+++ b/crates/router/src/configs/secrets_transformers.rs
@@ -498,6 +498,8 @@ pub(crate) async fn fetch_raw_secrets(
         decision: conf.decision,
         locker_based_open_banking_connectors: conf.locker_based_open_banking_connectors,
         grpc_client: conf.grpc_client,
+        #[cfg(feature = "v2")]
+        cell_information: conf.cell_information,
         network_tokenization_supported_card_networks: conf
             .network_tokenization_supported_card_networks,
         network_tokenization_service,
diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs
index 675b8c44e2a..0a7defc4063 100644
--- a/crates/router/src/configs/settings.rs
+++ b/crates/router/src/configs/settings.rs
@@ -122,6 +122,8 @@ pub struct Settings<S: SecretState> {
     pub decision: Option<DecisionConfig>,
     pub locker_based_open_banking_connectors: LockerBasedRecipientConnectorList,
     pub grpc_client: GrpcClientSettings,
+    #[cfg(feature = "v2")]
+    pub cell_information: CellInformation,
     pub network_tokenization_supported_card_networks: NetworkTokenizationSupportedCardNetworks,
     pub network_tokenization_service: Option<SecretStateContainer<NetworkTokenizationService, S>>,
     pub network_tokenization_supported_connectors: NetworkTokenizationSupportedConnectors,
@@ -854,6 +856,8 @@ impl Settings<SecuredSecret> {
         self.generic_link.payment_method_collect.validate()?;
         self.generic_link.payout_link.validate()?;
 
+        #[cfg(feature = "v2")]
+        self.cell_information.validate()?;
         self.network_tokenization_service
             .as_ref()
             .map(|x| x.get_inner().validate())
@@ -940,6 +944,26 @@ pub struct ServerTls {
     pub certificate: PathBuf,
 }
 
+#[cfg(feature = "v2")]
+#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
+pub struct CellInformation {
+    pub id: common_utils::id_type::CellId,
+}
+
+#[cfg(feature = "v2")]
+impl Default for CellInformation {
+    fn default() -> Self {
+        // We provide a static default cell id for constructing application settings.
+        // This will only panic at application startup if we're unable to construct the default,
+        // around the time of deserializing application settings.
+        // And a panic at application startup is considered acceptable.
+        #[allow(clippy::expect_used)]
+        let cell_id = common_utils::id_type::CellId::from_str("defid")
+            .expect("Failed to create a default for Cell Id");
+        Self { id: cell_id }
+    }
+}
+
 fn deserialize_hashmap_inner<K, V>(
     value: HashMap<String, String>,
 ) -> Result<HashMap<K, HashSet<V>>, String>
diff --git a/crates/router/src/configs/validations.rs b/crates/router/src/configs/validations.rs
index 67db7b1266c..7736d7b3f37 100644
--- a/crates/router/src/configs/validations.rs
+++ b/crates/router/src/configs/validations.rs
@@ -193,6 +193,19 @@ impl super::settings::GenericLinkEnvConfig {
     }
 }
 
+#[cfg(feature = "v2")]
+impl super::settings::CellInformation {
+    pub fn validate(&self) -> Result<(), ApplicationError> {
+        use common_utils::{fp_utils::when, id_type};
+
+        when(self == &super::settings::CellInformation::default(), || {
+            Err(ApplicationError::InvalidConfigurationValueError(
+                "CellId cannot be set to a default".into(),
+            ))
+        })
+    }
+}
+
 impl super::settings::NetworkTokenizationService {
     pub fn validate(&self) -> Result<(), ApplicationError> {
         use common_utils::fp_utils::when;

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

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

## Description
<!-- Describe your changes in detail -->
Added Cell Id in SessionState config
The strategy is use check the value of Cell id at application start and panic if it equals the default value.

### 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)?
-->
Cannot be tested, as setting the cell id as default in config will cause the application to panic.

## 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`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
