feat(users): refactor ProdIntent to support product-type context and merchant-scope (#7638)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Sandeep Kumar
2025-04-10 15:14:07 +05:30
committed by GitHub
parent 203ae3e97e
commit bbd2102274
10 changed files with 51 additions and 19 deletions

View File

@ -1,4 +1,4 @@
use common_enums::CountryAlpha2;
use common_enums::{CountryAlpha2, MerchantProductType};
use common_utils::{id_type, pii};
use masking::Secret;
use strum::EnumString;
@ -103,6 +103,8 @@ pub struct ProdIntent {
pub poc_contact: Option<String>,
pub comments: Option<String>,
pub is_completed: bool,
#[serde(default)]
pub product_type: MerchantProductType,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]

View File

@ -1,6 +1,7 @@
use serde;
use utoipa::ToSchema;
#[derive(
Copy,
Default,
Clone,
Debug,

View File

@ -2974,7 +2974,7 @@ pub async fn list_merchants_for_user_in_org(
.map(|merchant_account| user_api::UserMerchantAccountResponse {
merchant_name: merchant_account.merchant_name.clone(),
merchant_id: merchant_account.get_id().to_owned(),
product_type: merchant_account.product_type.clone(),
product_type: merchant_account.product_type,
version: merchant_account.version,
})
.collect::<Vec<_>>(),

View File

@ -38,7 +38,6 @@ pub async fn set_metadata(
Ok(ApplicationResponse::StatusOk)
}
#[cfg(feature = "v1")]
pub async fn get_multiple_metadata(
state: SessionState,
user: UserFromToken,
@ -462,7 +461,7 @@ async fn insert_metadata(
pii::Email::from_str(inner_poc_email)
.change_context(UserErrors::EmailParsingError)?;
}
let mut metadata = utils::insert_user_scoped_metadata_to_db(
let mut metadata = utils::insert_merchant_scoped_metadata_to_db(
state,
user.user_id.clone(),
user.merchant_id.clone(),
@ -473,7 +472,7 @@ async fn insert_metadata(
.await;
if utils::is_update_required(&metadata) {
metadata = utils::update_user_scoped_metadata(
metadata = utils::update_merchant_scoped_metadata(
state,
user.user_id.clone(),
user.merchant_id.clone(),
@ -500,7 +499,6 @@ async fn insert_metadata(
EntityType::Merchant,
)
.await?;
let email_contents = email_types::BizEmailProd::new(
state,
data,
@ -662,7 +660,6 @@ async fn fetch_metadata(
Ok(dashboard_metadata)
}
#[cfg(feature = "v1")]
pub async fn backfill_metadata(
state: &SessionState,
user: &UserFromToken,
@ -705,6 +702,11 @@ pub async fn backfill_metadata(
return Ok(None);
};
#[cfg(feature = "v1")]
let processor_name = mca.connector_name.clone();
#[cfg(feature = "v2")]
let processor_name = mca.connector_name.to_string().clone();
Some(
insert_metadata(
state,
@ -712,13 +714,14 @@ pub async fn backfill_metadata(
DBEnum::StripeConnected,
types::MetaData::StripeConnected(api::ProcessorConnected {
processor_id: mca.get_id(),
processor_name: mca.connector_name,
processor_name,
}),
)
.await,
)
.transpose()
}
DBEnum::PaypalConnected => {
let mca = if let Some(paypal_connected) = get_merchant_connector_account_by_name(
state,
@ -745,6 +748,11 @@ pub async fn backfill_metadata(
return Ok(None);
};
#[cfg(feature = "v1")]
let processor_name = mca.connector_name.clone();
#[cfg(feature = "v2")]
let processor_name = mca.connector_name.to_string().clone();
Some(
insert_metadata(
state,
@ -752,7 +760,7 @@ pub async fn backfill_metadata(
DBEnum::PaypalConnected,
types::MetaData::PaypalConnected(api::ProcessorConnected {
processor_id: mca.get_id(),
processor_name: mca.connector_name,
processor_name,
}),
)
.await,

View File

@ -2136,6 +2136,12 @@ impl User {
),
);
route = route.service(
web::resource("/data")
.route(web::get().to(user::get_multiple_dashboard_metadata))
.route(web::post().to(user::set_dashboard_metadata)),
);
route
}
}

View File

@ -197,7 +197,6 @@ pub async fn set_dashboard_metadata(
.await
}
#[cfg(feature = "v1")]
pub async fn get_multiple_dashboard_metadata(
state: web::Data<AppState>,
req: HttpRequest,

View File

@ -104,6 +104,10 @@
<strong>Business Website:</strong>
{business_website}
</li>
<li>
<strong>Product Type:</strong>
{product_type}
</li>
</ol>
</td>
</tr>

View File

@ -1,5 +1,5 @@
use api_models::user::dashboard_metadata::ProdIntent;
use common_enums::EntityType;
use common_enums::{EntityType, MerchantProductType};
use common_utils::{errors::CustomResult, pii, types::theme::EmailThemeConfig};
use error_stack::ResultExt;
use external_services::email::{EmailContents, EmailData, EmailError};
@ -64,6 +64,7 @@ pub enum EmailBody {
legal_business_name: String,
business_location: String,
business_website: String,
product_type: MerchantProductType,
},
ReconActivation {
user_name: String,
@ -199,6 +200,7 @@ pub mod html {
legal_business_name,
business_location,
business_website,
product_type,
} => {
format!(
include_str!("assets/bizemailprod.html"),
@ -207,6 +209,7 @@ pub mod html {
business_location = business_location,
business_website = business_website,
username = user_name,
product_type = product_type
)
}
EmailBody::ProFeatureRequest {
@ -558,6 +561,7 @@ pub struct BizEmailProd {
pub settings: std::sync::Arc<configs::Settings>,
pub theme_id: Option<String>,
pub theme_config: EmailThemeConfig,
pub product_type: MerchantProductType,
}
impl BizEmailProd {
@ -582,6 +586,7 @@ impl BizEmailProd {
business_website: data.business_website.unwrap_or_default(),
theme_id,
theme_config,
product_type: data.product_type,
})
}
}
@ -595,6 +600,7 @@ impl EmailData for BizEmailProd {
legal_business_name: self.legal_business_name.clone(),
business_location: self.business_location.clone(),
business_website: self.business_website.clone(),
product_type: self.product_type,
});
Ok(EmailContents {

View File

@ -417,7 +417,7 @@ impl NewUserMerchant {
}
pub fn get_product_type(&self) -> Option<common_enums::MerchantProductType> {
self.product_type.clone()
self.product_type
}
pub async fn check_if_already_exists_in_db(&self, state: SessionState) -> UserResult<()> {
@ -703,11 +703,18 @@ impl TryFrom<UserMerchantCreateRequestWithToken> for NewUserMerchant {
} else {
id_type::MerchantId::new_from_unix_timestamp()
};
let (user_from_storage, user_merchant_create, user_from_token) = value;
Ok(Self {
merchant_id,
company_name: Some(UserCompanyName::new(value.1.company_name.clone())?),
product_type: value.1.product_type.clone(),
new_organization: NewUserOrganization::from(value),
company_name: Some(UserCompanyName::new(
user_merchant_create.company_name.clone(),
)?),
product_type: user_merchant_create.product_type,
new_organization: NewUserOrganization::from((
user_from_storage,
user_merchant_create,
user_from_token,
)),
})
}
}

View File

@ -218,10 +218,9 @@ pub fn separate_metadata_type_based_on_scope(
| DBEnum::SetupWoocomWebhook
| DBEnum::OnboardingSurvey
| DBEnum::IsMultipleConfiguration
| DBEnum::ReconStatus => merchant_scoped.push(key),
DBEnum::Feedback | DBEnum::ProdIntent | DBEnum::IsChangePasswordRequired => {
user_scoped.push(key)
}
| DBEnum::ReconStatus
| DBEnum::ProdIntent => merchant_scoped.push(key),
DBEnum::Feedback | DBEnum::IsChangePasswordRequired => user_scoped.push(key),
}
}
(merchant_scoped, user_scoped)