mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 03:13:56 +08:00
refac: customer address db alter for gdpr compliance (#105)
This commit is contained in:
@ -2,7 +2,6 @@ use std::{convert::From, default::Default};
|
|||||||
|
|
||||||
use masking::{Secret, WithType};
|
use masking::{Secret, WithType};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
use crate::{pii::Email, types::api};
|
use crate::{pii::Email, types::api};
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ pub(crate) struct CustomerUpdateRequest {
|
|||||||
pub(crate) struct CreateCustomerResponse {
|
pub(crate) struct CreateCustomerResponse {
|
||||||
id: String,
|
id: String,
|
||||||
object: String,
|
object: String,
|
||||||
address: Option<Secret<serde_json::Value>>,
|
|
||||||
created: u64,
|
created: u64,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
email: Option<Secret<String, Email>>,
|
email: Option<Secret<String, Email>>,
|
||||||
@ -65,16 +63,6 @@ impl From<CreateCustomerRequest> for api::CustomerRequest {
|
|||||||
phone: req.phone,
|
phone: req.phone,
|
||||||
email: req.email,
|
email: req.email,
|
||||||
description: req.invoice_prefix,
|
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()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,17 +75,6 @@ impl From<CustomerUpdateRequest> for api::CustomerRequest {
|
|||||||
phone: req.phone,
|
phone: req.phone,
|
||||||
email: req.email,
|
email: req.email,
|
||||||
description: req.description,
|
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: req
|
||||||
.metadata
|
.metadata
|
||||||
.map(|v| serde_json::from_str(&v).ok())
|
.map(|v| serde_json::from_str(&v).ok())
|
||||||
@ -112,7 +89,6 @@ impl From<api::CustomerResponse> for CreateCustomerResponse {
|
|||||||
Self {
|
Self {
|
||||||
id: cust.customer_id,
|
id: cust.customer_id,
|
||||||
object: "customer".to_owned(),
|
object: "customer".to_owned(),
|
||||||
address: cust.address,
|
|
||||||
created: cust.created_at.assume_utc().unix_timestamp() as u64,
|
created: cust.created_at.assume_utc().unix_timestamp() as u64,
|
||||||
description: cust.description,
|
description: cust.description,
|
||||||
email: cust.email,
|
email: cust.email,
|
||||||
|
|||||||
@ -27,7 +27,6 @@ pub async fn create_customer(
|
|||||||
phone: customer_data.phone,
|
phone: customer_data.phone,
|
||||||
description: customer_data.description,
|
description: customer_data.description,
|
||||||
phone_country_code: customer_data.phone_country_code,
|
phone_country_code: customer_data.phone_country_code,
|
||||||
address: customer_data.address,
|
|
||||||
metadata: customer_data.metadata,
|
metadata: customer_data.metadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,7 +91,6 @@ pub async fn update_customer(
|
|||||||
email: update_customer.email,
|
email: update_customer.email,
|
||||||
phone: update_customer.phone,
|
phone: update_customer.phone,
|
||||||
phone_country_code: update_customer.phone_country_code,
|
phone_country_code: update_customer.phone_country_code,
|
||||||
address: update_customer.address,
|
|
||||||
metadata: update_customer.metadata,
|
metadata: update_customer.metadata,
|
||||||
description: update_customer.description,
|
description: update_customer.description,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -36,6 +36,8 @@ pub async fn get_address_for_payment_request(
|
|||||||
db: &dyn StorageInterface,
|
db: &dyn StorageInterface,
|
||||||
req_address: Option<&api::Address>,
|
req_address: Option<&api::Address>,
|
||||||
address_id: Option<&str>,
|
address_id: Option<&str>,
|
||||||
|
merchant_id: &str,
|
||||||
|
customer_id: &Option<String>,
|
||||||
) -> CustomResult<Option<storage::Address>, errors::ApiErrorResponse> {
|
) -> CustomResult<Option<storage::Address>, errors::ApiErrorResponse> {
|
||||||
// TODO: Refactor this function for more readability (TryFrom)
|
// TODO: Refactor this function for more readability (TryFrom)
|
||||||
Ok(match req_address {
|
Ok(match req_address {
|
||||||
@ -50,6 +52,10 @@ pub async fn get_address_for_payment_request(
|
|||||||
),
|
),
|
||||||
None => {
|
None => {
|
||||||
// generate a new address here
|
// generate a new address here
|
||||||
|
let customer_id = customer_id
|
||||||
|
.as_deref()
|
||||||
|
.get_required_value("customer_id")
|
||||||
|
.change_context(errors::ApiErrorResponse::CustomerNotFound)?;
|
||||||
Some(
|
Some(
|
||||||
db.insert_address(storage::AddressNew {
|
db.insert_address(storage::AddressNew {
|
||||||
city: address.address.as_ref().and_then(|a| a.city.clone()),
|
city: address.address.as_ref().and_then(|a| a.city.clone()),
|
||||||
@ -66,6 +72,8 @@ pub async fn get_address_for_payment_request(
|
|||||||
.phone
|
.phone
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|a| a.country_code.clone()),
|
.and_then(|a| a.country_code.clone()),
|
||||||
|
customer_id: customer_id.to_string(),
|
||||||
|
merchant_id: merchant_id.to_string(),
|
||||||
..storage::AddressNew::default()
|
..storage::AddressNew::default()
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -101,6 +101,8 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
|||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.shipping_address_id.as_deref(),
|
payment_intent.shipping_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -108,6 +110,8 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
|||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.billing_address_id.as_deref(),
|
payment_intent.billing_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -109,12 +109,16 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
db,
|
db,
|
||||||
request.shipping.as_ref(),
|
request.shipping.as_ref(),
|
||||||
payment_intent.shipping_address_id.as_deref(),
|
payment_intent.shipping_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let billing_address = helpers::get_address_for_payment_request(
|
let billing_address = helpers::get_address_for_payment_request(
|
||||||
db,
|
db,
|
||||||
request.billing.as_ref(),
|
request.billing.as_ref(),
|
||||||
payment_intent.billing_address_id.as_deref(),
|
payment_intent.billing_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -61,11 +61,23 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
|
helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let shipping_address =
|
let shipping_address = helpers::get_address_for_payment_request(
|
||||||
helpers::get_address_for_payment_request(db, request.shipping.as_ref(), None).await?;
|
db,
|
||||||
|
request.shipping.as_ref(),
|
||||||
|
None,
|
||||||
|
merchant_id,
|
||||||
|
&request.customer_id,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let billing_address =
|
let billing_address = helpers::get_address_for_payment_request(
|
||||||
helpers::get_address_for_payment_request(db, request.billing.as_ref(), None).await?;
|
db,
|
||||||
|
request.billing.as_ref(),
|
||||||
|
None,
|
||||||
|
merchant_id,
|
||||||
|
&request.customer_id,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let browser_info = request
|
let browser_info = request
|
||||||
.browser_info
|
.browser_info
|
||||||
|
|||||||
@ -82,6 +82,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
|||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.shipping_address_id.as_deref(),
|
payment_intent.shipping_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -89,6 +91,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
|||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.billing_address_id.as_deref(),
|
payment_intent.billing_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -72,12 +72,16 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
|||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.shipping_address_id.as_deref(),
|
payment_intent.shipping_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let billing_address = helpers::get_address_for_payment_request(
|
let billing_address = helpers::get_address_for_payment_request(
|
||||||
db,
|
db,
|
||||||
None,
|
None,
|
||||||
payment_intent.billing_address_id.as_deref(),
|
payment_intent.billing_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -96,12 +96,16 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
db,
|
db,
|
||||||
request.shipping.as_ref(),
|
request.shipping.as_ref(),
|
||||||
payment_intent.shipping_address_id.as_deref(),
|
payment_intent.shipping_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let billing_address = helpers::get_address_for_payment_request(
|
let billing_address = helpers::get_address_for_payment_request(
|
||||||
db,
|
db,
|
||||||
request.billing.as_ref(),
|
request.billing.as_ref(),
|
||||||
payment_intent.billing_address_id.as_deref(),
|
payment_intent.billing_address_id.as_deref(),
|
||||||
|
merchant_id,
|
||||||
|
&payment_intent.customer_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -136,7 +136,6 @@ impl CustomerInterface for MockDb {
|
|||||||
phone: customer_data.phone,
|
phone: customer_data.phone,
|
||||||
phone_country_code: customer_data.phone_country_code,
|
phone_country_code: customer_data.phone_country_code,
|
||||||
description: customer_data.description,
|
description: customer_data.description,
|
||||||
address: customer_data.address,
|
|
||||||
created_at: common_utils::date_time::now(),
|
created_at: common_utils::date_time::now(),
|
||||||
metadata: customer_data.metadata,
|
metadata: customer_data.metadata,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,6 +20,8 @@ diesel::table! {
|
|||||||
country_code -> Nullable<Varchar>,
|
country_code -> Nullable<Varchar>,
|
||||||
created_at -> Timestamp,
|
created_at -> Timestamp,
|
||||||
modified_at -> Timestamp,
|
modified_at -> Timestamp,
|
||||||
|
customer_id -> Varchar,
|
||||||
|
merchant_id -> Varchar,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +67,6 @@ diesel::table! {
|
|||||||
phone -> Nullable<Varchar>,
|
phone -> Nullable<Varchar>,
|
||||||
phone_country_code -> Nullable<Varchar>,
|
phone_country_code -> Nullable<Varchar>,
|
||||||
description -> Nullable<Varchar>,
|
description -> Nullable<Varchar>,
|
||||||
address -> Nullable<Json>,
|
|
||||||
created_at -> Timestamp,
|
created_at -> Timestamp,
|
||||||
metadata -> Nullable<Json>,
|
metadata -> Nullable<Json>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,6 @@ pub struct CustomerRequest {
|
|||||||
pub phone: Option<Secret<String>>,
|
pub phone: Option<Secret<String>>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub phone_country_code: Option<String>,
|
pub phone_country_code: Option<String>,
|
||||||
pub address: Option<Secret<serde_json::Value>>,
|
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,14 +34,6 @@ impl CustomerRequest {
|
|||||||
expected_format: "valid email address".to_string(),
|
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)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,7 +46,6 @@ pub struct CustomerResponse {
|
|||||||
pub phone: Option<Secret<String>>,
|
pub phone: Option<Secret<String>>,
|
||||||
pub phone_country_code: Option<String>,
|
pub phone_country_code: Option<String>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub address: Option<Secret<serde_json::Value>>,
|
|
||||||
#[serde(with = "custom_serde::iso8601")]
|
#[serde(with = "custom_serde::iso8601")]
|
||||||
pub created_at: time::PrimitiveDateTime,
|
pub created_at: time::PrimitiveDateTime,
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<serde_json::Value>,
|
||||||
@ -70,7 +60,6 @@ impl From<storage::Customer> for CustomerResponse {
|
|||||||
phone: cust.phone,
|
phone: cust.phone,
|
||||||
phone_country_code: cust.phone_country_code,
|
phone_country_code: cust.phone_country_code,
|
||||||
description: cust.description,
|
description: cust.description,
|
||||||
address: cust.address,
|
|
||||||
created_at: cust.created_at,
|
created_at: cust.created_at,
|
||||||
metadata: cust.metadata,
|
metadata: cust.metadata,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,8 @@ pub struct AddressNew {
|
|||||||
pub last_name: Option<Secret<String>>,
|
pub last_name: Option<Secret<String>>,
|
||||||
pub phone_number: Option<Secret<String>>,
|
pub phone_number: Option<Secret<String>>,
|
||||||
pub country_code: Option<String>,
|
pub country_code: Option<String>,
|
||||||
|
pub customer_id: String,
|
||||||
|
pub merchant_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)]
|
#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)]
|
||||||
@ -48,6 +50,8 @@ pub struct Address {
|
|||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
#[serde(with = "custom_serde::iso8601")]
|
#[serde(with = "custom_serde::iso8601")]
|
||||||
pub modified_at: PrimitiveDateTime,
|
pub modified_at: PrimitiveDateTime,
|
||||||
|
pub customer_id: String,
|
||||||
|
pub merchant_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -177,6 +181,8 @@ impl Default for AddressNew {
|
|||||||
last_name: None,
|
last_name: None,
|
||||||
phone_number: None,
|
phone_number: None,
|
||||||
country_code: None,
|
country_code: None,
|
||||||
|
customer_id: String::default(),
|
||||||
|
merchant_id: String::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,6 @@ pub struct CustomerNew {
|
|||||||
pub phone: Option<Secret<String>>,
|
pub phone: Option<Secret<String>>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub phone_country_code: Option<String>,
|
pub phone_country_code: Option<String>,
|
||||||
pub address: Option<Secret<serde_json::Value>>,
|
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +30,6 @@ pub struct Customer {
|
|||||||
pub phone: Option<Secret<String>>,
|
pub phone: Option<Secret<String>>,
|
||||||
pub phone_country_code: Option<String>,
|
pub phone_country_code: Option<String>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub address: Option<Secret<serde_json::Value>>,
|
|
||||||
pub created_at: PrimitiveDateTime,
|
pub created_at: PrimitiveDateTime,
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
@ -44,7 +42,6 @@ pub enum CustomerUpdate {
|
|||||||
phone: Option<Secret<String>>,
|
phone: Option<Secret<String>>,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
phone_country_code: Option<String>,
|
phone_country_code: Option<String>,
|
||||||
address: Option<Secret<serde_json::Value>>,
|
|
||||||
metadata: Option<serde_json::Value>,
|
metadata: Option<serde_json::Value>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -57,7 +54,6 @@ pub(super) struct CustomerUpdateInternal {
|
|||||||
phone: Option<Secret<String>>,
|
phone: Option<Secret<String>>,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
phone_country_code: Option<String>,
|
phone_country_code: Option<String>,
|
||||||
address: Option<Secret<serde_json::Value>>,
|
|
||||||
metadata: Option<serde_json::Value>,
|
metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +66,6 @@ impl From<CustomerUpdate> for CustomerUpdateInternal {
|
|||||||
phone,
|
phone,
|
||||||
description,
|
description,
|
||||||
phone_country_code,
|
phone_country_code,
|
||||||
address,
|
|
||||||
metadata,
|
metadata,
|
||||||
} => Self {
|
} => Self {
|
||||||
name,
|
name,
|
||||||
@ -78,7 +73,6 @@ impl From<CustomerUpdate> for CustomerUpdateInternal {
|
|||||||
phone,
|
phone,
|
||||||
description,
|
description,
|
||||||
phone_country_code,
|
phone_country_code,
|
||||||
address,
|
|
||||||
metadata,
|
metadata,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ pub(crate) use common_utils::{
|
|||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
ext_traits::{validate_address, OptionExt, ValidateCall},
|
ext_traits::{OptionExt, ValidateCall},
|
||||||
fp_utils::when,
|
fp_utils::when,
|
||||||
};
|
};
|
||||||
use crate::consts;
|
use crate::consts;
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
use common_utils::ext_traits::ValueExt;
|
use common_utils::ext_traits::ValueExt;
|
||||||
use error_stack::{report, IntoReport, Report, ResultExt};
|
use error_stack::{IntoReport, Report, ResultExt};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::errors::{self, ApiErrorResponse, CustomResult, RouterResult},
|
core::errors::{self, ApiErrorResponse, CustomResult, RouterResult},
|
||||||
types::api::AddressDetails,
|
|
||||||
utils::when,
|
utils::when,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,11 +128,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate_address(address: &serde_json::Value) -> CustomResult<(), errors::ValidationError> {
|
// pub fn validate_address(address: &serde_json::Value) -> CustomResult<(), errors::ValidationError> {
|
||||||
if let Err(err) = serde_json::from_value::<AddressDetails>(address.clone()) {
|
// if let Err(err) = serde_json::from_value::<AddressDetails>(address.clone()) {
|
||||||
return Err(report!(errors::ValidationError::InvalidValue {
|
// return Err(report!(errors::ValidationError::InvalidValue {
|
||||||
message: format!("Invalid address: {err}")
|
// message: format!("Invalid address: {err}")
|
||||||
}));
|
// }));
|
||||||
}
|
// }
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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;
|
||||||
Reference in New Issue
Block a user