diff --git a/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_created_ledger_entry.rs b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_created_ledger_entry.rs new file mode 100644 index 0000000000..7f51e16b8c --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_created_ledger_entry.rs @@ -0,0 +1,25 @@ +use crate::queries::wallet_ledger_entries::internal_insert_wallet_ledger_entry::InsertWalletLedgerEntry; +use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType; +use errors::AnyhowResult; +use sqlx::MySql; +use tokens::tokens::wallets::WalletToken; + +pub (crate) async fn internal_insert_wallet_created_ledger_entry( + wallet_token: &WalletToken, + transaction: &mut sqlx::Transaction<'_, MySql>, +) -> AnyhowResult<()> { + + let record = InsertWalletLedgerEntry { + wallet_token, + entry_type: WalletLedgerEntryType::Create, + maybe_entity_ref: None, + banked_credits_before: 0, + banked_credits_after: 0, + monthly_credits_before: 0, + monthly_credits_after: 0, + }; + + record.upsert_with_transaction(transaction).await?; + + Ok(()) +} diff --git a/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_ledger_entry.rs b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_ledger_entry.rs index e45b4b7ed6..c224ca9458 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_ledger_entry.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/internal_insert_wallet_ledger_entry.rs @@ -10,7 +10,7 @@ use tokens::tokens::wallets::WalletToken; // TODO: Make a trait (eg. `InsertableRecord`, `UpsertableRecord`) with default impls to handle common query concerns. -pub struct InsertWalletLedgerEntry<'a> { +pub (crate) struct InsertWalletLedgerEntry<'a> { /// The wallet pub wallet_token: &'a WalletToken, diff --git a/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/mod.rs b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/mod.rs index 3a99fbfaf0..46661ede68 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/mod.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallet_ledger_entries/mod.rs @@ -1 +1,2 @@ -pub (crate) mod internal_insert_wallet_ledger_entry; \ No newline at end of file +pub (crate) mod internal_insert_wallet_ledger_entry; +pub mod internal_insert_wallet_created_ledger_entry; \ No newline at end of file diff --git a/crates/schema/database/mysql_queries/src/queries/wallets/add_durable_banked_balance_to_wallet.rs b/crates/schema/database/mysql_queries/src/queries/wallets/add_durable_banked_balance_to_wallet.rs index 3d5008425f..7dd7a076cd 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallets/add_durable_banked_balance_to_wallet.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallets/add_durable_banked_balance_to_wallet.rs @@ -1,5 +1,7 @@ +use crate::queries::wallet_ledger_entries::internal_insert_wallet_ledger_entry::InsertWalletLedgerEntry; use crate::queries::wallets::internal_select_wallet_balance_for_update::internal_select_wallet_balance_for_update; use crate::queries::wallets::wallet_update_summary::WalletUpdateSummary; +use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType; use sqlx::MySql; use tokens::tokens::wallets::WalletToken; @@ -15,9 +17,9 @@ pub async fn add_durable_banked_balance_to_wallet( transaction ).await?; - let existing_balance = wallet.banked_credits; - let new_balance = existing_balance.saturating_add(amount_to_add); - + let existing_banked_balance = wallet.banked_credits; + let new_banked_balance = existing_banked_balance.saturating_add(amount_to_add); + // TODO: Insert ledger event. let result = sqlx::query!( @@ -29,17 +31,38 @@ pub async fn add_durable_banked_balance_to_wallet( WHERE token = ? LIMIT 1 "#, - new_balance, + new_banked_balance, wallet_token.as_str(), ).execute(&mut **transaction) .await?; + let record = InsertWalletLedgerEntry { + wallet_token, + entry_type: WalletLedgerEntryType::CreditBanked, + maybe_entity_ref: None, // TODO + + // Updated banked credits + banked_credits_before: existing_banked_balance, + banked_credits_after: new_banked_balance, + + // Unchanged monthly credits + monthly_credits_before: wallet.monthly_credits, + monthly_credits_after: wallet.monthly_credits, + }; + + record.upsert_with_transaction(transaction).await?; + + Ok(WalletUpdateSummary { token: wallet.token, owner_user_token: wallet.owner_user_token, - banked_credits_now: new_balance, + + // Updated banked credits + banked_credits_before: existing_banked_balance, + banked_credits_now: new_banked_balance, + + // Unchanged monthly credits monthly_credits_now: wallet.monthly_credits, - banked_credits_before: wallet.banked_credits, monthly_credits_before: wallet.monthly_credits, }) } \ No newline at end of file diff --git a/crates/schema/database/mysql_queries/src/queries/wallets/create_new_wallet_for_owner_user.rs b/crates/schema/database/mysql_queries/src/queries/wallets/create_new_wallet_for_owner_user.rs index 6c24776bcf..7de352499d 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallets/create_new_wallet_for_owner_user.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallets/create_new_wallet_for_owner_user.rs @@ -1,3 +1,4 @@ +use crate::queries::wallet_ledger_entries::internal_insert_wallet_created_ledger_entry::internal_insert_wallet_created_ledger_entry; use errors::AnyhowResult; use sqlx::MySql; use tokens::tokens::users::UserToken; @@ -26,8 +27,11 @@ SET .execute(&mut **transaction) .await; - match result { - Ok(_) => Ok(token), - Err(e) => Err(anyhow::anyhow!("Database query error when creating wallet: {}", e)), + if let Err(err) = result { + return Err(anyhow::anyhow!("Database query error when creating wallet: {}", err)); } + + internal_insert_wallet_created_ledger_entry(&token, transaction).await?; + + Ok(token) } diff --git a/crates/schema/database/mysql_queries/src/queries/wallets/refill_monthly_credits_balance_on_wallet.rs b/crates/schema/database/mysql_queries/src/queries/wallets/refill_monthly_credits_balance_on_wallet.rs index 5215b3434f..bcf6241350 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallets/refill_monthly_credits_balance_on_wallet.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallets/refill_monthly_credits_balance_on_wallet.rs @@ -1,5 +1,7 @@ +use crate::queries::wallet_ledger_entries::internal_insert_wallet_ledger_entry::InsertWalletLedgerEntry; use crate::queries::wallets::internal_select_wallet_balance_for_update::internal_select_wallet_balance_for_update; use crate::queries::wallets::wallet_update_summary::WalletUpdateSummary; +use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType; use sqlx::MySql; use tokens::tokens::wallets::WalletToken; @@ -15,10 +17,8 @@ pub async fn refill_monthly_credits_balance_on_wallet( transaction ).await?; - let existing_balance = wallet.monthly_credits; - let new_balance = monthly_amount; - - // TODO: Insert ledger event. + let existing_monthly_balance = wallet.monthly_credits; + let new_monthly_balance = monthly_amount; let result = sqlx::query!( r#" @@ -29,21 +29,37 @@ pub async fn refill_monthly_credits_balance_on_wallet( WHERE token = ? LIMIT 1 "#, - new_balance, + new_monthly_balance, wallet_token.as_str(), ).execute(&mut **transaction) .await?; + let record = InsertWalletLedgerEntry { + wallet_token, + entry_type: WalletLedgerEntryType::CreditMonthly, + maybe_entity_ref: None, // TODO + + monthly_credits_before: existing_monthly_balance, + monthly_credits_after: new_monthly_balance, + + // Unchanged + banked_credits_before: wallet.banked_credits, + banked_credits_after: wallet.banked_credits, + }; + + record.upsert_with_transaction(transaction).await?; + + Ok(WalletUpdateSummary { token: wallet.token, owner_user_token: wallet.owner_user_token, // We updated monthly credits - monthly_credits_now: new_balance, - monthly_credits_before: wallet.monthly_credits, + monthly_credits_before: existing_monthly_balance, + monthly_credits_now: new_monthly_balance, // Banked credits not touched - banked_credits_now: wallet.banked_credits, banked_credits_before: wallet.banked_credits, + banked_credits_now: wallet.banked_credits, }) } diff --git a/crates/schema/database/mysql_queries/src/queries/wallets/wallet_update_summary.rs b/crates/schema/database/mysql_queries/src/queries/wallets/wallet_update_summary.rs index 34c4416586..7225fdef61 100644 --- a/crates/schema/database/mysql_queries/src/queries/wallets/wallet_update_summary.rs +++ b/crates/schema/database/mysql_queries/src/queries/wallets/wallet_update_summary.rs @@ -7,7 +7,7 @@ pub struct WalletUpdateSummary { pub banked_credits_now: u64, pub monthly_credits_now: u64, - + pub banked_credits_before: u64, pub monthly_credits_before: u64, } diff --git a/crates/schema/public/enums/src/by_table/wallet_ledger_entries/wallet_ledger_entry_type.rs b/crates/schema/public/enums/src/by_table/wallet_ledger_entries/wallet_ledger_entry_type.rs index 721f47ae1c..b3f9928c52 100644 --- a/crates/schema/public/enums/src/by_table/wallet_ledger_entries/wallet_ledger_entry_type.rs +++ b/crates/schema/public/enums/src/by_table/wallet_ledger_entries/wallet_ledger_entry_type.rs @@ -17,9 +17,9 @@ pub enum WalletLedgerEntryType { #[serde(rename = "create")] Create, - /// Credit durable balance - #[serde(rename = "credit_durable")] - CreditDurable, + /// Credit durable banked balance + #[serde(rename = "credit_banked")] + CreditBanked, /// Credit monthly refill #[serde(rename = "credit_monthly")] @@ -29,9 +29,9 @@ pub enum WalletLedgerEntryType { #[serde(rename = "deduct_mixed")] DeductMixed, - /// Deduct durable credits - #[serde(rename = "deduct_durable")] - DeductDurable, + /// Deduct durable banked credits + #[serde(rename = "deduct_banked")] + DeductBanked, /// Deduct monthly credits #[serde(rename = "deduct_monthly")] @@ -48,10 +48,10 @@ impl WalletLedgerEntryType { pub fn to_str(&self) -> &'static str { match self { Self::Create => "create", - Self::CreditDurable => "credit_durable", + Self::CreditBanked => "credit_banked", Self::CreditMonthly => "credit_monthly", Self::DeductMixed => "deduct_mixed", - Self::DeductDurable => "deduct_durable", + Self::DeductBanked => "deduct_banked", Self::DeductMonthly => "deduct_monthly", } } @@ -59,10 +59,10 @@ impl WalletLedgerEntryType { pub fn from_str(value: &str) -> Result { match value { "create" => Ok(Self::Create), - "credit_durable" => Ok(Self::CreditDurable), + "credit_banked" => Ok(Self::CreditBanked), "credit_monthly" => Ok(Self::CreditMonthly), "deduct_mixed" => Ok(Self::DeductMixed), - "deduct_durable" => Ok(Self::DeductDurable), + "deduct_banked" => Ok(Self::DeductBanked), "deduct_monthly" => Ok(Self::DeductMonthly), _ => Err(format!("invalid value: {:?}", value)), } @@ -73,10 +73,10 @@ impl WalletLedgerEntryType { // NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc. BTreeSet::from([ Self::Create, - Self::CreditDurable, + Self::CreditBanked, Self::CreditMonthly, Self::DeductMixed, - Self::DeductDurable, + Self::DeductBanked, Self::DeductMonthly, ]) } @@ -93,10 +93,10 @@ mod tests { #[test] fn test_serialization() { assert_serialization(WalletLedgerEntryType::Create, "create"); - assert_serialization(WalletLedgerEntryType::CreditDurable, "credit_durable"); + assert_serialization(WalletLedgerEntryType::CreditBanked, "credit_banked"); assert_serialization(WalletLedgerEntryType::CreditMonthly, "credit_monthly"); assert_serialization(WalletLedgerEntryType::DeductMixed, "deduct_mixed"); - assert_serialization(WalletLedgerEntryType::DeductDurable, "deduct_durable"); + assert_serialization(WalletLedgerEntryType::DeductBanked, "deduct_banked"); assert_serialization(WalletLedgerEntryType::DeductMonthly, "deduct_monthly"); } } @@ -107,20 +107,20 @@ mod tests { #[test] fn to_str() { assert_eq!(WalletLedgerEntryType::Create.to_str(), "create"); - assert_eq!(WalletLedgerEntryType::CreditDurable.to_str(), "credit_durable"); + assert_eq!(WalletLedgerEntryType::CreditBanked.to_str(), "credit_banked"); assert_eq!(WalletLedgerEntryType::CreditMonthly.to_str(), "credit_monthly"); assert_eq!(WalletLedgerEntryType::DeductMixed.to_str(), "deduct_mixed"); - assert_eq!(WalletLedgerEntryType::DeductDurable.to_str(), "deduct_durable"); + assert_eq!(WalletLedgerEntryType::DeductBanked.to_str(), "deduct_banked"); assert_eq!(WalletLedgerEntryType::DeductMonthly.to_str(), "deduct_monthly"); } #[test] fn from_str() { assert_eq!(WalletLedgerEntryType::from_str("create").unwrap(), WalletLedgerEntryType::Create); - assert_eq!(WalletLedgerEntryType::from_str("credit_durable").unwrap(), WalletLedgerEntryType::CreditDurable); + assert_eq!(WalletLedgerEntryType::from_str("credit_banked").unwrap(), WalletLedgerEntryType::CreditBanked); assert_eq!(WalletLedgerEntryType::from_str("credit_monthly").unwrap(), WalletLedgerEntryType::CreditMonthly); assert_eq!(WalletLedgerEntryType::from_str("deduct_mixed").unwrap(), WalletLedgerEntryType::DeductMixed); - assert_eq!(WalletLedgerEntryType::from_str("deduct_durable").unwrap(), WalletLedgerEntryType::DeductDurable); + assert_eq!(WalletLedgerEntryType::from_str("deduct_banked").unwrap(), WalletLedgerEntryType::DeductBanked); assert_eq!(WalletLedgerEntryType::from_str("deduct_monthly").unwrap(), WalletLedgerEntryType::DeductMonthly); assert!(WalletLedgerEntryType::from_str("foo").is_err()); } @@ -134,10 +134,10 @@ mod tests { let mut variants = WalletLedgerEntryType::all_variants(); assert_eq!(variants.len(), 6); assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::Create)); - assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::CreditDurable)); + assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::CreditBanked)); assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::CreditMonthly)); assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::DeductMixed)); - assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::DeductDurable)); + assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::DeductBanked)); assert_eq!(variants.pop_first(), Some(WalletLedgerEntryType::DeductMonthly)); assert_eq!(variants.pop_first(), None); }