From affa9fc35a54d16e0092dd47dee35a359b39435a Mon Sep 17 00:00:00 2001 From: Manoj Ghorela <118727120+manoj-juspay@users.noreply.github.com> Date: Mon, 12 Dec 2022 00:19:33 +0530 Subject: [PATCH] refac: customer address db alter for gdpr compliance (#105) --- .../compatibility/stripe/customers/types.rs | 24 ------------------- crates/router/src/core/customers.rs | 2 -- crates/router/src/core/payments/helpers.rs | 8 +++++++ .../payments/operations/payment_capture.rs | 4 ++++ .../payments/operations/payment_confirm.rs | 4 ++++ .../payments/operations/payment_create.rs | 20 ++++++++++++---- .../payments/operations/payment_session.rs | 4 ++++ .../core/payments/operations/payment_start.rs | 4 ++++ .../payments/operations/payment_update.rs | 4 ++++ crates/router/src/db/customers.rs | 1 - crates/router/src/schema.rs | 3 ++- crates/router/src/types/api/customers.rs | 11 --------- crates/router/src/types/storage/address.rs | 6 +++++ crates/router/src/types/storage/customers.rs | 6 ----- crates/router/src/utils.rs | 2 +- crates/router/src/utils/ext_traits.rs | 19 +++++++-------- .../down.sql | 6 +++++ .../up.sql | 8 +++++++ 18 files changed, 76 insertions(+), 60 deletions(-) create mode 100644 migrations/2022-12-10-123613_update_address_and_customer/down.sql create mode 100644 migrations/2022-12-10-123613_update_address_and_customer/up.sql diff --git a/crates/router/src/compatibility/stripe/customers/types.rs b/crates/router/src/compatibility/stripe/customers/types.rs index 7da952234e..e5b5be732a 100644 --- a/crates/router/src/compatibility/stripe/customers/types.rs +++ b/crates/router/src/compatibility/stripe/customers/types.rs @@ -2,7 +2,6 @@ use std::{convert::From, default::Default}; use masking::{Secret, WithType}; use serde::{Deserialize, Serialize}; -use serde_json::json; use crate::{pii::Email, types::api}; @@ -39,7 +38,6 @@ pub(crate) struct CustomerUpdateRequest { pub(crate) struct CreateCustomerResponse { id: String, object: String, - address: Option>, created: u64, description: Option, email: Option>, @@ -65,16 +63,6 @@ impl From for api::CustomerRequest { phone: req.phone, email: req.email, description: req.invoice_prefix, - address: req.address.map(|addr| { - Secret::new(json!({ - "city": addr.city, - "country": addr.country, - "line1": addr.line1, - "line2": addr.line2, - "postal_code": addr.postal_code, - "state": addr.state - })) - }), ..Default::default() } } @@ -87,17 +75,6 @@ impl From for api::CustomerRequest { phone: req.phone, email: req.email, description: req.description, - address: req.address.map(|addr| { - Secret::new(json!({ - "city": addr.city, - "country": addr.country, - "line1": addr.line1, - "line2": addr.line2, - "postal_code": addr.postal_code, - "state": addr.state - })) - }), - metadata: req .metadata .map(|v| serde_json::from_str(&v).ok()) @@ -112,7 +89,6 @@ impl From for CreateCustomerResponse { Self { id: cust.customer_id, object: "customer".to_owned(), - address: cust.address, created: cust.created_at.assume_utc().unix_timestamp() as u64, description: cust.description, email: cust.email, diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index 9d4b23be57..c5d0acdd89 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -27,7 +27,6 @@ pub async fn create_customer( phone: customer_data.phone, description: customer_data.description, phone_country_code: customer_data.phone_country_code, - address: customer_data.address, metadata: customer_data.metadata, }; @@ -92,7 +91,6 @@ pub async fn update_customer( email: update_customer.email, phone: update_customer.phone, phone_country_code: update_customer.phone_country_code, - address: update_customer.address, metadata: update_customer.metadata, description: update_customer.description, }, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 2a7b231469..f09454ba08 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -36,6 +36,8 @@ pub async fn get_address_for_payment_request( db: &dyn StorageInterface, req_address: Option<&api::Address>, address_id: Option<&str>, + merchant_id: &str, + customer_id: &Option, ) -> CustomResult, errors::ApiErrorResponse> { // TODO: Refactor this function for more readability (TryFrom) Ok(match req_address { @@ -50,6 +52,10 @@ pub async fn get_address_for_payment_request( ), None => { // generate a new address here + let customer_id = customer_id + .as_deref() + .get_required_value("customer_id") + .change_context(errors::ApiErrorResponse::CustomerNotFound)?; Some( db.insert_address(storage::AddressNew { city: address.address.as_ref().and_then(|a| a.city.clone()), @@ -66,6 +72,8 @@ pub async fn get_address_for_payment_request( .phone .as_ref() .and_then(|a| a.country_code.clone()), + customer_id: customer_id.to_string(), + merchant_id: merchant_id.to_string(), ..storage::AddressNew::default() }) .await diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 5256a90bc3..bfad77e603 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -101,6 +101,8 @@ impl GetTracker, api::PaymentsCaptu db, None, payment_intent.shipping_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; @@ -108,6 +110,8 @@ impl GetTracker, api::PaymentsCaptu db, None, payment_intent.billing_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 3705f9504f..b4a062806c 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -109,12 +109,16 @@ impl GetTracker, api::PaymentsRequest> for Pa db, request.shipping.as_ref(), payment_intent.shipping_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; let billing_address = helpers::get_address_for_payment_request( db, request.billing.as_ref(), payment_intent.billing_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index feb3dd00fe..3d1b1cde4c 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -61,11 +61,23 @@ impl GetTracker, api::PaymentsRequest> for Pa helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id) .await?; - let shipping_address = - helpers::get_address_for_payment_request(db, request.shipping.as_ref(), None).await?; + let shipping_address = helpers::get_address_for_payment_request( + db, + request.shipping.as_ref(), + None, + merchant_id, + &request.customer_id, + ) + .await?; - let billing_address = - helpers::get_address_for_payment_request(db, request.billing.as_ref(), None).await?; + let billing_address = helpers::get_address_for_payment_request( + db, + request.billing.as_ref(), + None, + merchant_id, + &request.customer_id, + ) + .await?; let browser_info = request .browser_info diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index 809bafa8b1..8b777a06bc 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -82,6 +82,8 @@ impl GetTracker, api::PaymentsSessionRequest> db, None, payment_intent.shipping_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; @@ -89,6 +91,8 @@ impl GetTracker, api::PaymentsSessionRequest> db, None, payment_intent.billing_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index bf1c2135d4..17e66296a5 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -72,12 +72,16 @@ impl GetTracker, api::PaymentsStartRequest> f db, None, payment_intent.shipping_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; let billing_address = helpers::get_address_for_payment_request( db, None, payment_intent.billing_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 7d4ec45b7d..09b8ed76e8 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -96,12 +96,16 @@ impl GetTracker, api::PaymentsRequest> for Pa db, request.shipping.as_ref(), payment_intent.shipping_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; let billing_address = helpers::get_address_for_payment_request( db, request.billing.as_ref(), payment_intent.billing_address_id.as_deref(), + merchant_id, + &payment_intent.customer_id, ) .await?; diff --git a/crates/router/src/db/customers.rs b/crates/router/src/db/customers.rs index df76c74e78..7bcfd969aa 100644 --- a/crates/router/src/db/customers.rs +++ b/crates/router/src/db/customers.rs @@ -136,7 +136,6 @@ impl CustomerInterface for MockDb { phone: customer_data.phone, phone_country_code: customer_data.phone_country_code, description: customer_data.description, - address: customer_data.address, created_at: common_utils::date_time::now(), metadata: customer_data.metadata, }; diff --git a/crates/router/src/schema.rs b/crates/router/src/schema.rs index c719ba473a..218c2305bc 100644 --- a/crates/router/src/schema.rs +++ b/crates/router/src/schema.rs @@ -20,6 +20,8 @@ diesel::table! { country_code -> Nullable, created_at -> Timestamp, modified_at -> Timestamp, + customer_id -> Varchar, + merchant_id -> Varchar, } } @@ -65,7 +67,6 @@ diesel::table! { phone -> Nullable, phone_country_code -> Nullable, description -> Nullable, - address -> Nullable, created_at -> Timestamp, metadata -> Nullable, } diff --git a/crates/router/src/types/api/customers.rs b/crates/router/src/types/api/customers.rs index 91aa8d7a20..1800307369 100644 --- a/crates/router/src/types/api/customers.rs +++ b/crates/router/src/types/api/customers.rs @@ -21,7 +21,6 @@ pub struct CustomerRequest { pub phone: Option>, pub description: Option, pub phone_country_code: Option, - pub address: Option>, pub metadata: Option, } @@ -35,14 +34,6 @@ impl CustomerRequest { expected_format: "valid email address".to_string(), })?; - self.address - .as_ref() - .validate_opt(|addr| utils::validate_address(addr.peek())) - .change_context(errors::ApiErrorResponse::InvalidDataFormat { - field_name: "address".to_string(), - expected_format: "valid address".to_string(), - })?; - Ok(self) } } @@ -55,7 +46,6 @@ pub struct CustomerResponse { pub phone: Option>, pub phone_country_code: Option, pub description: Option, - pub address: Option>, #[serde(with = "custom_serde::iso8601")] pub created_at: time::PrimitiveDateTime, pub metadata: Option, @@ -70,7 +60,6 @@ impl From for CustomerResponse { phone: cust.phone, phone_country_code: cust.phone_country_code, description: cust.description, - address: cust.address, created_at: cust.created_at, metadata: cust.metadata, } diff --git a/crates/router/src/types/storage/address.rs b/crates/router/src/types/storage/address.rs index 8a638cdd57..2eb24884c9 100644 --- a/crates/router/src/types/storage/address.rs +++ b/crates/router/src/types/storage/address.rs @@ -22,6 +22,8 @@ pub struct AddressNew { pub last_name: Option>, pub phone_number: Option>, pub country_code: Option, + pub customer_id: String, + pub merchant_id: String, } #[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] @@ -48,6 +50,8 @@ pub struct Address { #[serde(skip_serializing)] #[serde(with = "custom_serde::iso8601")] pub modified_at: PrimitiveDateTime, + pub customer_id: String, + pub merchant_id: String, } #[derive(Debug)] @@ -177,6 +181,8 @@ impl Default for AddressNew { last_name: None, phone_number: None, country_code: None, + customer_id: String::default(), + merchant_id: String::default(), } } } diff --git a/crates/router/src/types/storage/customers.rs b/crates/router/src/types/storage/customers.rs index 99afe44b22..58f48a9ed5 100644 --- a/crates/router/src/types/storage/customers.rs +++ b/crates/router/src/types/storage/customers.rs @@ -16,7 +16,6 @@ pub struct CustomerNew { pub phone: Option>, pub description: Option, pub phone_country_code: Option, - pub address: Option>, pub metadata: Option, } @@ -31,7 +30,6 @@ pub struct Customer { pub phone: Option>, pub phone_country_code: Option, pub description: Option, - pub address: Option>, pub created_at: PrimitiveDateTime, pub metadata: Option, } @@ -44,7 +42,6 @@ pub enum CustomerUpdate { phone: Option>, description: Option, phone_country_code: Option, - address: Option>, metadata: Option, }, } @@ -57,7 +54,6 @@ pub(super) struct CustomerUpdateInternal { phone: Option>, description: Option, phone_country_code: Option, - address: Option>, metadata: Option, } @@ -70,7 +66,6 @@ impl From for CustomerUpdateInternal { phone, description, phone_country_code, - address, metadata, } => Self { name, @@ -78,7 +73,6 @@ impl From for CustomerUpdateInternal { phone, description, phone_country_code, - address, metadata, }, } diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs index e5836829a9..ef0b24a69e 100644 --- a/crates/router/src/utils.rs +++ b/crates/router/src/utils.rs @@ -12,7 +12,7 @@ pub(crate) use common_utils::{ use nanoid::nanoid; pub(crate) use self::{ - ext_traits::{validate_address, OptionExt, ValidateCall}, + ext_traits::{OptionExt, ValidateCall}, fp_utils::when, }; use crate::consts; diff --git a/crates/router/src/utils/ext_traits.rs b/crates/router/src/utils/ext_traits.rs index 43bd298781..e0cf6dea55 100644 --- a/crates/router/src/utils/ext_traits.rs +++ b/crates/router/src/utils/ext_traits.rs @@ -1,9 +1,8 @@ use common_utils::ext_traits::ValueExt; -use error_stack::{report, IntoReport, Report, ResultExt}; +use error_stack::{IntoReport, Report, ResultExt}; use crate::{ core::errors::{self, ApiErrorResponse, CustomResult, RouterResult}, - types::api::AddressDetails, utils::when, }; @@ -129,11 +128,11 @@ where } } -pub fn validate_address(address: &serde_json::Value) -> CustomResult<(), errors::ValidationError> { - if let Err(err) = serde_json::from_value::(address.clone()) { - return Err(report!(errors::ValidationError::InvalidValue { - message: format!("Invalid address: {err}") - })); - } - Ok(()) -} +// pub fn validate_address(address: &serde_json::Value) -> CustomResult<(), errors::ValidationError> { +// if let Err(err) = serde_json::from_value::(address.clone()) { +// return Err(report!(errors::ValidationError::InvalidValue { +// message: format!("Invalid address: {err}") +// })); +// } +// Ok(()) +// } diff --git a/migrations/2022-12-10-123613_update_address_and_customer/down.sql b/migrations/2022-12-10-123613_update_address_and_customer/down.sql new file mode 100644 index 0000000000..305d085762 --- /dev/null +++ b/migrations/2022-12-10-123613_update_address_and_customer/down.sql @@ -0,0 +1,6 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE address +DROP COLUMN customer_id, +DROP COLUMN merchant_id; + +ALTER TABLE customers ADD COLUMN address JSON; \ No newline at end of file diff --git a/migrations/2022-12-10-123613_update_address_and_customer/up.sql b/migrations/2022-12-10-123613_update_address_and_customer/up.sql new file mode 100644 index 0000000000..e560ee0754 --- /dev/null +++ b/migrations/2022-12-10-123613_update_address_and_customer/up.sql @@ -0,0 +1,8 @@ +-- Your SQL goes here +ALTER TABLE address +ADD COLUMN customer_id VARCHAR(255) NOT NULL, +ADD COLUMN merchant_id VARCHAR(255) NOT NULL; + +CREATE INDEX address_customer_id_merchant_id_index ON address (customer_id, merchant_id); + +ALTER TABLE customers DROP COLUMN address; \ No newline at end of file