diff --git a/api/src/entities/mod.rs b/api/src/entities/mod.rs index a6f7ac7..481b844 100644 --- a/api/src/entities/mod.rs +++ b/api/src/entities/mod.rs @@ -15,3 +15,4 @@ pub mod nft_transfers; pub mod project_wallets; pub mod purchases; pub mod sea_orm_active_enums; +pub mod transfer_charges; diff --git a/api/src/entities/nft_transfers.rs b/api/src/entities/nft_transfers.rs index cd09f93..3e6f260 100644 --- a/api/src/entities/nft_transfers.rs +++ b/api/src/entities/nft_transfers.rs @@ -12,7 +12,6 @@ pub struct Model { pub sender: String, pub recipient: String, pub created_at: DateTimeWithTimeZone, - pub credits_deduction_id: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/api/src/entities/prelude.rs b/api/src/entities/prelude.rs index 558e1f9..bb51a6b 100644 --- a/api/src/entities/prelude.rs +++ b/api/src/entities/prelude.rs @@ -6,5 +6,5 @@ pub use super::{ drops::Entity as Drops, metadata_json_attributes::Entity as MetadataJsonAttributes, metadata_json_files::Entity as MetadataJsonFiles, metadata_jsons::Entity as MetadataJsons, nft_transfers::Entity as NftTransfers, project_wallets::Entity as ProjectWallets, - purchases::Entity as Purchases, + purchases::Entity as Purchases, transfer_charges::Entity as TransferCharges, }; diff --git a/api/src/entities/transfer_charges.rs b/api/src/entities/transfer_charges.rs new file mode 100644 index 0000000..5efe18f --- /dev/null +++ b/api/src/entities/transfer_charges.rs @@ -0,0 +1,16 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.5 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "transfer_charges")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub credits_deduction_id: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/api/src/events.rs b/api/src/events.rs index 4637fd1..48211c6 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -17,6 +17,7 @@ use crate::{ prelude::{CollectionMints, Purchases}, project_wallets, purchases, sea_orm_active_enums::{Blockchain, CreationStatus}, + transfer_charges, }, proto::{ nft_events::Event as NftEvent, @@ -163,7 +164,6 @@ impl Processor { sender: Set(payload.sender), recipient: Set(payload.recipient), created_at: Set(Utc::now().into()), - credits_deduction_id: Set(None), ..Default::default() }; @@ -210,7 +210,6 @@ impl Processor { sender: Set(mint.owner), recipient: Set(new_owner.clone()), created_at: Set(created_at), - credits_deduction_id: Set(None), ..Default::default() }; @@ -392,22 +391,14 @@ impl Processor { let conn = self.db.get(); let transfer_id = Uuid::from_str(&id)?; - let (nft_transfer, collection_mint) = nft_transfers::Entity::find_by_id(transfer_id) - .find_also_related(collection_mints::Entity) + let transfer_charge = transfer_charges::Entity::find() + .filter(transfer_charges::Column::CreditsDeductionId.eq(transfer_id)) .one(conn) .await? - .context("failed to load nft transfer from db")?; + .context("failed to load transfer charge from db")?; - let collection_mint = collection_mint.context("collection mint not found")?; - - let mut collection_mint_am: collection_mints::ActiveModel = collection_mint.into(); - let mut nft_transfer_am: nft_transfers::ActiveModel = nft_transfer.clone().into(); - - if let TransferResult::Success(signature) = payload { - collection_mint_am.owner = Set(nft_transfer.recipient.clone()); - nft_transfer_am.tx_signature = Set(Some(signature)); - - let deduction_id = nft_transfer + if let TransferResult::Success(_) = payload { + let deduction_id = transfer_charge .credits_deduction_id .context("deduction id not found")?; @@ -416,9 +407,6 @@ impl Processor { .await?; } - collection_mint_am.update(conn).await?; - nft_transfer_am.insert(conn).await?; - Ok(()) } } diff --git a/api/src/mutations/transfer.rs b/api/src/mutations/transfer.rs index 6a87253..96a3d5b 100644 --- a/api/src/mutations/transfer.rs +++ b/api/src/mutations/transfer.rs @@ -9,9 +9,10 @@ use crate::{ db::Connection, entities::{ collection_mints::{self, CollectionMint}, - collections, customer_wallets, drops, nft_transfers, + collections, customer_wallets, drops, prelude::{Collections, CustomerWallets, Drops}, sea_orm_active_enums::{Blockchain, CreationStatus}, + transfer_charges, }, proto::{self, NftEventKey, TransferPolygonAsset}, Actions, AppContext, OrganizationId, UserID, @@ -95,17 +96,13 @@ impl Mutation { .await? .ok_or(Error::new("Sender wallet is not managed by Hub"))?; - let nft_transfer_am = nft_transfers::ActiveModel { - tx_signature: Set(None), - collection_mint_id: Set(collection_mint_model.id), - sender: Set(owner_address.clone()), - recipient: Set(recipient.clone()), + let transfer_charges_am = transfer_charges::ActiveModel { ..Default::default() }; - let nft_transfer_model = nft_transfer_am.insert(conn).await?; + let transfer_charge_model = transfer_charges_am.insert(conn).await?; let event_key = NftEventKey { - id: nft_transfer_model.id.to_string(), + id: transfer_charge_model.id.to_string(), user_id: user_id.to_string(), project_id: drop.project_id.to_string(), }; @@ -149,7 +146,7 @@ impl Mutation { balance, org_id, user_id, - nft_transfer_model.id, + transfer_charge_model.id, collection.blockchain, ) .await?; @@ -188,14 +185,15 @@ async fn submit_pending_deduction( let deduction_id = id.ok_or(Error::new("Organization does not have enough credits"))?; - let nft_transfer_model = nft_transfers::Entity::find_by_id(transfer_id) + let transfer_charge_model = transfer_charges::Entity::find() + .filter(transfer_charges::Column::Id.eq(transfer_id)) .one(db.get()) .await? - .ok_or(Error::new("drop not found"))?; + .ok_or(Error::new("transfer charge not found"))?; - let mut nft_transfer: nft_transfers::ActiveModel = nft_transfer_model.into(); - nft_transfer.credits_deduction_id = Set(Some(deduction_id.0)); - nft_transfer.update(db.get()).await?; + let mut transfer_charge: transfer_charges::ActiveModel = transfer_charge_model.into(); + transfer_charge.credits_deduction_id = Set(Some(deduction_id.0)); + transfer_charge.update(db.get()).await?; Ok(()) } diff --git a/migration/src/lib.rs b/migration/src/lib.rs index f318209..daa2236 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -41,6 +41,9 @@ mod m20230518_034021_set_default_timestamp; mod m20230606_121315_add_collection_mint_id_to_nft_transfers; mod m20230620_160452_make_address_nullable_on_collection_mints; mod m20230626_111748_customer_wallets_table; +mod m20230706_130934_create_transfer_charges_table; +mod m20230706_133356_backfill_transfer_charges; +mod m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers; pub struct Migrator; @@ -89,6 +92,9 @@ impl MigratorTrait for Migrator { Box::new(m20230606_121315_add_collection_mint_id_to_nft_transfers::Migration), Box::new(m20230620_160452_make_address_nullable_on_collection_mints::Migration), Box::new(m20230626_111748_customer_wallets_table::Migration), + Box::new(m20230706_130934_create_transfer_charges_table::Migration), + Box::new(m20230706_133356_backfill_transfer_charges::Migration), + Box::new(m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers::Migration), ] } } diff --git a/migration/src/m20230706_130934_create_transfer_charges_table.rs b/migration/src/m20230706_130934_create_transfer_charges_table.rs new file mode 100644 index 0000000..50ebdbe --- /dev/null +++ b/migration/src/m20230706_130934_create_transfer_charges_table.rs @@ -0,0 +1,44 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(TransferCharges::Table) + .if_not_exists() + .col( + ColumnDef::new(TransferCharges::Id) + .uuid() + .not_null() + .primary_key() + .extra("default gen_random_uuid()".to_string()), + ) + .col( + ColumnDef::new(TransferCharges::CreditsDeductionId) + .uuid() + .null(), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(TransferCharges::Table).to_owned()) + .await + } +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum TransferCharges { + Table, + Id, + CreditsDeductionId, +} diff --git a/migration/src/m20230706_133356_backfill_transfer_charges.rs b/migration/src/m20230706_133356_backfill_transfer_charges.rs new file mode 100644 index 0000000..d44ce7f --- /dev/null +++ b/migration/src/m20230706_133356_backfill_transfer_charges.rs @@ -0,0 +1,34 @@ +use sea_orm::{ConnectionTrait, Statement}; +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + + let stmt = Statement::from_string( + manager.get_database_backend(), + r#"INSERT INTO transfer_charges(credits_deduction_id) SELECT credits_deduction_id FROM nft_transfers;"#.to_string(), + ); + + db.execute(stmt).await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + + let stmt = Statement::from_string( + manager.get_database_backend(), + r#"DELETE FROM transfer_charges;"#.to_string(), + ); + + db.execute(stmt).await?; + + Ok(()) + } +} diff --git a/migration/src/m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers.rs b/migration/src/m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers.rs new file mode 100644 index 0000000..60dc631 --- /dev/null +++ b/migration/src/m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers.rs @@ -0,0 +1,40 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(NftTransfers::Table) + .drop_column(NftTransfers::CreditsDeductionId) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(NftTransfers::Table) + .add_column_if_not_exists( + ColumnDef::new(NftTransfers::CreditsDeductionId) + .uuid() + .null(), + ) + .to_owned(), + ) + .await + } +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum NftTransfers { + Table, + CreditsDeductionId, +}