diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index b39aab94f1..4bf857edb7 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -313,3 +313,25 @@ pub enum Country { Zambia, Zimbabwe, } + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + Default, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, +)] +#[router_derive::diesel_enum(storage_type = "text")] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum FileUploadProvider { + #[default] + Router, + Stripe, + Checkout, +} diff --git a/crates/router/src/connector/checkout.rs b/crates/router/src/connector/checkout.rs index 900428e78f..aba8556626 100644 --- a/crates/router/src/connector/checkout.rs +++ b/crates/router/src/connector/checkout.rs @@ -118,6 +118,7 @@ impl api::ConnectorAccessToken for Checkout {} impl api::AcceptDispute for Checkout {} impl api::PaymentToken for Checkout {} impl api::Dispute for Checkout {} +impl api::RetrieveFile for Checkout {} impl api::DefendDispute for Checkout {} impl @@ -773,6 +774,12 @@ impl impl api::UploadFile for Checkout {} +impl + ConnectorIntegration + for Checkout +{ +} + #[async_trait::async_trait] impl api::FileUpload for Checkout { fn validate_file_upload( diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 60630f595d..02cf834549 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -1199,6 +1199,98 @@ impl } } +impl api::RetrieveFile for Stripe {} + +impl + services::ConnectorIntegration< + api::Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, + > for Stripe +{ + fn get_headers( + &self, + req: &types::RouterData< + api::Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, + >, + _connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + self.get_auth_header(&req.connector_auth_type) + } + + fn get_url( + &self, + req: &types::RetrieveFileRouterData, + connectors: &settings::Connectors, + ) -> CustomResult { + Ok(format!( + "{}v1/files/{}/contents", + connectors.stripe.base_url_file_upload, req.request.provider_file_id + )) + } + + fn build_request( + &self, + req: &types::RetrieveFileRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Get) + .url(&types::RetrieveFileType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RetrieveFileType::get_headers(self, req, connectors)?) + .build(), + )) + } + + #[instrument(skip_all)] + fn handle_response( + &self, + data: &types::RetrieveFileRouterData, + res: types::Response, + ) -> CustomResult< + types::RouterData< + api::Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, + >, + errors::ConnectorError, + > { + let response = res.response; + Ok(types::RetrieveFileRouterData { + response: Ok(types::RetrieveFileResponse { + file_data: response.to_vec(), + }), + ..data.clone() + }) + } + + fn get_error_response( + &self, + res: types::Response, + ) -> CustomResult { + let response: stripe::ErrorResponse = res + .response + .parse_struct("ErrorResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + Ok(types::ErrorResponse { + status_code: res.status_code, + code: response + .error + .code + .unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()), + message: response + .error + .message + .unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()), + reason: None, + }) + } +} + impl api::SubmitEvidence for Stripe {} impl diff --git a/crates/router/src/core/disputes/transformers.rs b/crates/router/src/core/disputes/transformers.rs index 63a3697413..25c69571a0 100644 --- a/crates/router/src/core/disputes/transformers.rs +++ b/crates/router/src/core/disputes/transformers.rs @@ -3,7 +3,7 @@ use common_utils::errors::CustomResult; use crate::{ core::{errors, files::helpers::retrieve_file_and_provider_file_id_from_file_id}, routes::AppState, - types::SubmitEvidenceRequestData, + types::{api, SubmitEvidenceRequestData}, }; pub async fn get_evidence_request_data( @@ -17,6 +17,7 @@ pub async fn get_evidence_request_data( state, evidence_request.cancellation_policy, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (customer_communication, customer_communication_provider_file_id) = @@ -24,6 +25,7 @@ pub async fn get_evidence_request_data( state, evidence_request.customer_communication, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (customer_signature, customer_signature_provider_file_id) = @@ -31,12 +33,14 @@ pub async fn get_evidence_request_data( state, evidence_request.customer_signature, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (receipt, receipt_provider_file_id) = retrieve_file_and_provider_file_id_from_file_id( state, evidence_request.receipt, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (refund_policy, refund_policy_provider_file_id) = @@ -44,6 +48,7 @@ pub async fn get_evidence_request_data( state, evidence_request.refund_policy, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (service_documentation, service_documentation_provider_file_id) = @@ -51,6 +56,7 @@ pub async fn get_evidence_request_data( state, evidence_request.service_documentation, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (shipping_documentation, shipping_documentation_provider_file_id) = @@ -58,6 +64,7 @@ pub async fn get_evidence_request_data( state, evidence_request.shipping_documentation, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let ( @@ -67,6 +74,7 @@ pub async fn get_evidence_request_data( state, evidence_request.invoice_showing_distinct_transactions, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (recurring_transaction_agreement, recurring_transaction_agreement_provider_file_id) = @@ -74,6 +82,7 @@ pub async fn get_evidence_request_data( state, evidence_request.recurring_transaction_agreement, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; let (uncategorized_file, uncategorized_file_provider_file_id) = @@ -81,6 +90,7 @@ pub async fn get_evidence_request_data( state, evidence_request.uncategorized_file, merchant_account, + api::FileDataRequired::NotRequired, ) .await?; Ok(SubmitEvidenceRequestData { diff --git a/crates/router/src/core/files.rs b/crates/router/src/core/files.rs index 718f5f2923..32ff6f84b3 100644 --- a/crates/router/src/core/files.rs +++ b/crates/router/src/core/files.rs @@ -13,7 +13,7 @@ use crate::{ consts, routes::AppState, services::{self, ApplicationResponse}, - types::{api, storage, transformers::ForeignInto}, + types::{api, storage}, }; pub async fn files_create_core( @@ -37,6 +37,7 @@ pub async fn files_create_core( provider_file_id: None, file_upload_provider: None, available: false, + connector_label: None, }; let file_metadata_object = state .store @@ -44,8 +45,8 @@ pub async fn files_create_core( .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to insert file_metadata")?; - let (provider_file_id, file_upload_provider) = - helpers::upload_and_get_provider_provider_file_id( + let (provider_file_id, file_upload_provider, connector_label) = + helpers::upload_and_get_provider_provider_file_id_connector_label( state, &merchant_account, &create_file_request, @@ -55,8 +56,9 @@ pub async fn files_create_core( //Update file metadata let update_file_metadata = storage_models::file::FileMetadataUpdate::Update { provider_file_id: Some(provider_file_id), - file_upload_provider: Some(file_upload_provider.foreign_into()), + file_upload_provider: Some(file_upload_provider), available: true, + connector_label, }; state .store @@ -102,6 +104,7 @@ pub async fn files_retrieve_core( state, Some(req.file_id), &merchant_account, + api::FileDataRequired::Required, ) .await?; let content_type = file_metadata_object diff --git a/crates/router/src/core/files/helpers.rs b/crates/router/src/core/files/helpers.rs index a6a01fe09b..71a50d7fdc 100644 --- a/crates/router/src/core/files/helpers.rs +++ b/crates/router/src/core/files/helpers.rs @@ -6,11 +6,13 @@ use futures::TryStreamExt; use crate::{ core::{ errors::{self, StorageErrorExt}, - files, payments, utils, + files, + payments::{self, helpers as payments_helpers}, + utils, }, routes::AppState, services, - types::{self, api, storage}, + types::{self, api, storage, transformers::ForeignTryFrom}, }; pub async fn read_string(field: &mut Field) -> Option { @@ -144,10 +146,66 @@ pub async fn delete_file_using_file_id( } } +pub async fn retrieve_file_from_connector( + state: &AppState, + file_metadata: storage_models::file::FileMetadata, + merchant_account: &storage_models::merchant_account::MerchantAccount, +) -> CustomResult, errors::ApiErrorResponse> { + let connector = &types::Connector::foreign_try_from( + file_metadata + .file_upload_provider + .ok_or(errors::ApiErrorResponse::InternalServerError) + .into_report() + .attach_printable("Missing file upload provider")?, + )? + .to_string(); + let connector_data = api::ConnectorData::get_connector_by_name( + &state.conf.connectors, + connector, + api::GetToken::Connector, + )?; + let connector_integration: services::BoxedConnectorIntegration< + '_, + api::Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, + > = connector_data.connector.get_connector_integration(); + let router_data = utils::construct_retrieve_file_router_data( + state, + merchant_account, + &file_metadata, + connector, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed constructing the retrieve file router data")?; + let response = services::execute_connector_processing_step( + state, + connector_integration, + &router_data, + payments::CallConnectorAction::Trigger, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed while calling retrieve file connector api")?; + let retrieve_file_response = + response + .response + .map_err(|err| errors::ApiErrorResponse::ExternalConnectorError { + code: err.code, + message: err.message, + connector: connector.to_string(), + status_code: err.status_code, + reason: err.reason, + })?; + Ok(retrieve_file_response.file_data) +} + pub async fn retrieve_file_and_provider_file_id_from_file_id( state: &AppState, file_id: Option, merchant_account: &storage_models::merchant_account::MerchantAccount, + is_connector_file_data_required: api::FileDataRequired, ) -> CustomResult<(Option>, Option), errors::ApiErrorResponse> { match file_id { None => Ok((None, None)), @@ -159,10 +217,13 @@ pub async fn retrieve_file_and_provider_file_id_from_file_id( .change_context(errors::ApiErrorResponse::FileNotFound)?; let (provider, provider_file_id) = match ( file_metadata_object.file_upload_provider, - file_metadata_object.provider_file_id, + file_metadata_object.provider_file_id.clone(), + file_metadata_object.available, ) { - (Some(provider), Some(provider_file_id)) => (provider, provider_file_id), - _ => Err(errors::ApiErrorResponse::FileNotFound)?, + (Some(provider), Some(provider_file_id), true) => (provider, provider_file_id), + _ => Err(errors::ApiErrorResponse::FileNotAvailable) + .into_report() + .attach_printable("File not available")?, }; match provider { storage_models::enums::FileUploadProvider::Router => Ok(( @@ -176,20 +237,39 @@ pub async fn retrieve_file_and_provider_file_id_from_file_id( ), Some(provider_file_id), )), - //TODO: Handle Retrieve for other providers - _ => Ok((None, Some(provider_file_id))), + _ => { + let connector_file_data = match is_connector_file_data_required { + api::FileDataRequired::Required => Some( + retrieve_file_from_connector( + state, + file_metadata_object, + merchant_account, + ) + .await?, + ), + api::FileDataRequired::NotRequired => None, + }; + Ok((connector_file_data, Some(provider_file_id))) + } } } } } //Upload file to connector if it supports / store it in S3 and return file_upload_provider, provider_file_id accordingly -pub async fn upload_and_get_provider_provider_file_id( +pub async fn upload_and_get_provider_provider_file_id_connector_label( state: &AppState, merchant_account: &storage::merchant_account::MerchantAccount, create_file_request: &api::CreateFileRequest, file_key: String, -) -> CustomResult<(String, api::FileUploadProvider), errors::ApiErrorResponse> { +) -> CustomResult< + ( + String, + api_models::enums::FileUploadProvider, + Option, + ), + errors::ApiErrorResponse, +> { match create_file_request.purpose { api::FilePurpose::DisputeEvidence => { let dispute_id = create_file_request @@ -225,6 +305,12 @@ pub async fn upload_and_get_provider_provider_file_id( ) .await .change_context(errors::ApiErrorResponse::PaymentNotFound)?; + let connector_label = payments_helpers::get_connector_label( + payment_intent.business_country, + &payment_intent.business_label, + payment_attempt.business_sub_label.as_ref(), + &dispute.connector, + ); let connector_integration: services::BoxedConnectorIntegration< '_, api::Upload, @@ -239,6 +325,7 @@ pub async fn upload_and_get_provider_provider_file_id( create_file_request, &dispute.connector, file_key, + connector_label.clone(), ) .await .change_context(errors::ApiErrorResponse::InternalServerError) @@ -263,7 +350,10 @@ pub async fn upload_and_get_provider_provider_file_id( })?; Ok(( upload_file_response.provider_file_id, - api::FileUploadProvider::try_from(&connector_data.connector_name)?, + api_models::enums::FileUploadProvider::foreign_try_from( + &connector_data.connector_name, + )?, + Some(connector_label), )) } else { upload_file( @@ -273,7 +363,11 @@ pub async fn upload_and_get_provider_provider_file_id( create_file_request.file.clone(), ) .await?; - Ok((file_key, api::FileUploadProvider::Router)) + Ok(( + file_key, + api_models::enums::FileUploadProvider::Router, + None, + )) } } } diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index 03d578daea..0ec52df1f3 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -324,6 +324,14 @@ macro_rules! default_imp_for_file_upload{ types::UploadFileResponse, > for $path::$connector {} + impl api::RetrieveFile for $path::$connector {} + impl + services::ConnectorIntegration< + api::Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, + > for $path::$connector + {} )* }; } diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 4611cc3ebc..5b5f6e8ba2 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use api_models::enums::{DisputeStage, DisputeStatus}; use common_utils::errors::CustomResult; -use error_stack::ResultExt; +use error_stack::{IntoReport, ResultExt}; use router_env::{instrument, tracing}; use super::payments::{helpers, PaymentAddress}; @@ -343,6 +343,7 @@ pub async fn construct_submit_evidence_router_data<'a>( } #[instrument(skip_all)] +#[allow(clippy::too_many_arguments)] pub async fn construct_upload_file_router_data<'a>( state: &'a AppState, payment_intent: &'a storage::PaymentIntent, @@ -351,13 +352,8 @@ pub async fn construct_upload_file_router_data<'a>( create_file_request: &types::api::CreateFileRequest, connector_id: &str, file_key: String, + connector_label: String, ) -> RouterResult { - let connector_label = helpers::get_connector_label( - payment_intent.business_country, - &payment_intent.business_label, - payment_attempt.business_sub_label.as_ref(), - connector_id, - ); let merchant_connector_account = helpers::get_merchant_connector_account( state, merchant_account.merchant_id.as_str(), @@ -465,3 +461,62 @@ pub async fn construct_defend_dispute_router_data<'a>( }; Ok(router_data) } + +#[instrument(skip_all)] +pub async fn construct_retrieve_file_router_data<'a>( + state: &'a AppState, + merchant_account: &storage::MerchantAccount, + file_metadata: &storage_models::file::FileMetadata, + connector_id: &str, +) -> RouterResult { + let connector_label = file_metadata + .connector_label + .clone() + .ok_or(errors::ApiErrorResponse::InternalServerError) + .into_report() + .attach_printable("Missing connector label")?; + let merchant_connector_account = helpers::get_merchant_connector_account( + state, + merchant_account.merchant_id.as_str(), + &connector_label, + None, + ) + .await?; + let auth_type: types::ConnectorAuthType = merchant_connector_account + .get_connector_account_details() + .parse_value("ConnectorAuthType") + .change_context(errors::ApiErrorResponse::InternalServerError)?; + let router_data = types::RouterData { + flow: PhantomData, + merchant_id: merchant_account.merchant_id.clone(), + connector: connector_id.to_string(), + customer_id: None, + connector_customer: None, + payment_id: "irrelevant_payment_id_in_dispute_flow".to_string(), + attempt_id: "irrelevant_attempt_id_in_dispute_flow".to_string(), + status: storage_models::enums::AttemptStatus::default(), + payment_method: storage_models::enums::PaymentMethod::default(), + connector_auth_type: auth_type, + description: None, + return_url: None, + payment_method_id: None, + address: PaymentAddress::default(), + auth_type: storage_models::enums::AuthenticationType::default(), + connector_meta_data: merchant_connector_account.get_metadata(), + amount_captured: None, + request: types::RetrieveFileRequestData { + provider_file_id: file_metadata + .provider_file_id + .clone() + .ok_or(errors::ApiErrorResponse::InternalServerError) + .into_report() + .attach_printable("Missing provider file id")?, + }, + response: Err(types::ErrorResponse::default()), + access_token: None, + session_token: None, + reference_id: None, + payment_method_token: None, + }; + Ok(router_data) +} diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index d0750db413..aa01bf5ba7 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -136,6 +136,12 @@ pub type SubmitEvidenceType = dyn services::ConnectorIntegration< pub type UploadFileType = dyn services::ConnectorIntegration; +pub type RetrieveFileType = dyn services::ConnectorIntegration< + api::Retrieve, + RetrieveFileRequestData, + RetrieveFileResponse, +>; + pub type DefendDisputeType = dyn services::ConnectorIntegration< api::Defend, DefendDisputeRequestData, @@ -152,6 +158,9 @@ pub type SubmitEvidenceRouterData = pub type UploadFileRouterData = RouterData; +pub type RetrieveFileRouterData = + RouterData; + pub type DefendDisputeRouterData = RouterData; @@ -516,6 +525,16 @@ pub struct UploadFileResponse { pub provider_file_id: String, } +#[derive(Clone, Debug)] +pub struct RetrieveFileRequestData { + pub provider_file_id: String, +} + +#[derive(Clone, Debug)] +pub struct RetrieveFileResponse { + pub file_data: Vec, +} + #[derive(Debug, Clone, Default, serde::Deserialize, serde::Serialize)] pub struct ConnectorResponse { pub merchant_id: String, diff --git a/crates/router/src/types/api/files.rs b/crates/router/src/types/api/files.rs index eaf4015ccd..1e78708c81 100644 --- a/crates/router/src/types/api/files.rs +++ b/crates/router/src/types/api/files.rs @@ -1,23 +1,41 @@ +use api_models::enums::FileUploadProvider; use masking::{Deserialize, Serialize}; use super::ConnectorCommon; -use crate::{core::errors, services, types}; +use crate::{ + core::errors, + services, + types::{self, transformers::ForeignTryFrom}, +}; #[derive(Default, Debug, Deserialize, Serialize)] pub struct FileId { pub file_id: String, } -#[derive(Debug, Clone, frunk::LabelledGeneric)] -pub enum FileUploadProvider { - Router, - Stripe, - Checkout, +#[derive(Debug)] +pub enum FileDataRequired { + Required, + NotRequired, } -impl TryFrom<&types::Connector> for FileUploadProvider { +impl ForeignTryFrom for types::Connector { type Error = error_stack::Report; - fn try_from(item: &types::Connector) -> Result { + fn foreign_try_from(item: FileUploadProvider) -> Result { + match item { + FileUploadProvider::Stripe => Ok(Self::Stripe), + FileUploadProvider::Checkout => Ok(Self::Checkout), + FileUploadProvider::Router => Err(errors::ApiErrorResponse::NotSupported { + message: "File upload provider is not a connector".to_owned(), + } + .into()), + } + } +} + +impl ForeignTryFrom<&types::Connector> for FileUploadProvider { + type Error = error_stack::Report; + fn foreign_try_from(item: &types::Connector) -> Result { match *item { types::Connector::Stripe => Ok(Self::Stripe), types::Connector::Checkout => Ok(Self::Checkout), @@ -54,7 +72,19 @@ pub trait UploadFile: { } -pub trait FileUpload: ConnectorCommon + Sync + UploadFile { +#[derive(Debug, Clone)] +pub struct Retrieve; + +pub trait RetrieveFile: + services::ConnectorIntegration< + Retrieve, + types::RetrieveFileRequestData, + types::RetrieveFileResponse, +> +{ +} + +pub trait FileUpload: ConnectorCommon + Sync + UploadFile + RetrieveFile { fn validate_file_upload( &self, _purpose: FilePurpose, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index e57ee3a662..2b7b393783 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -457,12 +457,6 @@ impl ForeignFrom for api_enums::DisputeStatus { } } -impl ForeignFrom for storage_enums::FileUploadProvider { - fn foreign_from(provider: api_types::FileUploadProvider) -> Self { - frunk::labelled_convert_from(provider) - } -} - impl ForeignTryFrom for storage_enums::DisputeStatus { type Error = errors::ValidationError; diff --git a/crates/storage_models/src/enums.rs b/crates/storage_models/src/enums.rs index d197369f69..fea5949a43 100644 --- a/crates/storage_models/src/enums.rs +++ b/crates/storage_models/src/enums.rs @@ -796,26 +796,3 @@ pub enum DisputeStatus { DisputeWon, DisputeLost, } - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - Default, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - frunk::LabelledGeneric, -)] -#[router_derive::diesel_enum(storage_type = "text")] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum FileUploadProvider { - #[default] - Router, - Stripe, - Checkout, -} diff --git a/crates/storage_models/src/file.rs b/crates/storage_models/src/file.rs index 08363c2cbf..baa37507e9 100644 --- a/crates/storage_models/src/file.rs +++ b/crates/storage_models/src/file.rs @@ -2,7 +2,7 @@ use common_utils::custom_serde; use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; use masking::{Deserialize, Serialize}; -use crate::{enums as storage_enums, schema::file_metadata}; +use crate::schema::file_metadata; #[derive(Clone, Debug, Deserialize, Insertable, Serialize, router_derive::DebugAsDisplay)] #[diesel(table_name = file_metadata)] @@ -14,8 +14,9 @@ pub struct FileMetadataNew { pub file_size: i32, pub file_type: String, pub provider_file_id: Option, - pub file_upload_provider: Option, + pub file_upload_provider: Option, pub available: bool, + pub connector_label: Option, } #[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] @@ -28,18 +29,20 @@ pub struct FileMetadata { pub file_size: i32, pub file_type: String, pub provider_file_id: Option, - pub file_upload_provider: Option, + pub file_upload_provider: Option, pub available: bool, #[serde(with = "custom_serde::iso8601")] pub created_at: time::PrimitiveDateTime, + pub connector_label: Option, } #[derive(Debug)] pub enum FileMetadataUpdate { Update { provider_file_id: Option, - file_upload_provider: Option, + file_upload_provider: Option, available: bool, + connector_label: Option, }, } @@ -47,8 +50,9 @@ pub enum FileMetadataUpdate { #[diesel(table_name = file_metadata)] pub struct FileMetadataUpdateInternal { provider_file_id: Option, - file_upload_provider: Option, + file_upload_provider: Option, available: bool, + connector_label: Option, } impl From for FileMetadataUpdateInternal { @@ -58,10 +62,12 @@ impl From for FileMetadataUpdateInternal { provider_file_id, file_upload_provider, available, + connector_label, } => Self { provider_file_id, file_upload_provider, available, + connector_label, }, } } diff --git a/crates/storage_models/src/schema.rs b/crates/storage_models/src/schema.rs index 3ab3793d8d..2aadb280e1 100644 --- a/crates/storage_models/src/schema.rs +++ b/crates/storage_models/src/schema.rs @@ -169,6 +169,7 @@ diesel::table! { file_upload_provider -> Nullable, available -> Bool, created_at -> Timestamp, + connector_label -> Nullable, } } diff --git a/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/down.sql b/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/down.sql new file mode 100644 index 0000000000..33e2ddaad1 --- /dev/null +++ b/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/down.sql @@ -0,0 +1 @@ +ALTER TABLE file_metadata DROP COLUMN connector_label; \ No newline at end of file diff --git a/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/up.sql b/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/up.sql new file mode 100644 index 0000000000..9db889b900 --- /dev/null +++ b/migrations/2023-04-25-141011_add_connector_label_col_in_file_metadata/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here +ALTER TABLE file_metadata +ADD COLUMN connector_label VARCHAR(255); \ No newline at end of file