mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-10 12:01:36 +00:00
share refund logic
This commit is contained in:
1 parent
1b4d3e0f4b
commit
f8e400019d
6 files changed
+59
-147
No files matched your search
@@ -0,0 +1 @@
|
||||
pub mod refund_wallet_after_api_failure;
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
use log::{error, info};
|
||||
use mysql_queries::queries::wallets::refund::try_to_refund_ledger_entry::{try_to_refund_ledger_entry, WalletRefundOutcome};
|
||||
use sqlx::Acquire;
|
||||
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
|
||||
|
||||
pub async fn refund_wallet_after_api_failure(
|
||||
ledger_entry_token: &WalletLedgerEntryToken,
|
||||
connection: &mut sqlx::pool::PoolConnection<sqlx::MySql>,
|
||||
) {
|
||||
let mut transaction = match connection.begin().await {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to begin refund transaction after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match try_to_refund_ledger_entry(ledger_entry_token, &mut transaction).await {
|
||||
Ok(WalletRefundOutcome::Refunded(summary)) => {
|
||||
info!(
|
||||
"Refunded {} credits after API failure (ledger {} → refund ledger {}).",
|
||||
summary.refund_amount,
|
||||
ledger_entry_token.as_str(),
|
||||
summary.refund_ledger_entry_token.as_str(),
|
||||
);
|
||||
if let Err(err) = transaction.commit().await {
|
||||
error!(
|
||||
"Failed to commit refund after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(WalletRefundOutcome::AlreadyRefunded) => {
|
||||
info!(
|
||||
"Ledger entry {} was already refunded; no action needed.",
|
||||
ledger_entry_token.as_str()
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to refund ledger entry {} after API failure: {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-49
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::billing::wallets::attempt_wallet_deduction::attempt_wallet_deduction_else_common_web_error;
|
||||
use crate::http_server::common_responses::common_web_error::CommonWebError;
|
||||
use crate::http_server::endpoint_helpers::refund_wallet_after_api_failure::refund_wallet_after_api_failure;
|
||||
use crate::http_server::endpoints::generate::common::payments_error_test::payments_error_test;
|
||||
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
|
||||
use crate::state::server_state::ServerState;
|
||||
@@ -20,7 +21,6 @@ use mysql_queries::queries::generic_inference::worldlabs::insert_generic_inferen
|
||||
use mysql_queries::queries::idepotency_tokens::insert_idempotency_token::insert_idempotency_token;
|
||||
use mysql_queries::queries::prompt_context_items::insert_batch_prompt_context_items::{insert_batch_prompt_context_items, InsertBatchArgs, PromptContextItem};
|
||||
use mysql_queries::queries::prompts::insert_prompt::{insert_prompt, InsertPromptArgs};
|
||||
use mysql_queries::queries::wallets::refund::try_to_refund_ledger_entry::{try_to_refund_ledger_entry, WalletRefundOutcome};
|
||||
use sqlx::Acquire;
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use world_labs_api::api::api_types::world_labs_model::WorldLabsModel;
|
||||
@@ -155,7 +155,7 @@ pub async fn generate_worldlabs_marble_0p1_mini_splat_handler(
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
warn!("World Labs generate_world error: {:?}", err);
|
||||
refund_after_api_failure(&wallet_deduction.ledger_entry_token, &mut mysql_connection).await;
|
||||
refund_wallet_after_api_failure(&wallet_deduction.ledger_entry_token, &mut mysql_connection).await;
|
||||
return Err(CommonWebError::ServerError);
|
||||
}
|
||||
};
|
||||
@@ -247,50 +247,3 @@ pub async fn generate_worldlabs_marble_0p1_mini_splat_handler(
|
||||
inference_job_token: job_token,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn refund_after_api_failure(
|
||||
ledger_entry_token: &tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken,
|
||||
connection: &mut sqlx::pool::PoolConnection<sqlx::MySql>,
|
||||
) {
|
||||
let mut transaction = match connection.begin().await {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to begin refund transaction after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match try_to_refund_ledger_entry(ledger_entry_token, &mut transaction).await {
|
||||
Ok(WalletRefundOutcome::Refunded(summary)) => {
|
||||
info!(
|
||||
"Refunded {} credits after API failure (ledger {} → refund ledger {}).",
|
||||
summary.refund_amount,
|
||||
ledger_entry_token.as_str(),
|
||||
summary.refund_ledger_entry_token.as_str(),
|
||||
);
|
||||
if let Err(err) = transaction.commit().await {
|
||||
error!(
|
||||
"Failed to commit refund after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(WalletRefundOutcome::AlreadyRefunded) => {
|
||||
info!(
|
||||
"Ledger entry {} was already refunded; no action needed.",
|
||||
ledger_entry_token.as_str()
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to refund ledger entry {} after API failure: {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-49
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::billing::wallets::attempt_wallet_deduction::attempt_wallet_deduction_else_common_web_error;
|
||||
use crate::http_server::common_responses::common_web_error::CommonWebError;
|
||||
use crate::http_server::endpoint_helpers::refund_wallet_after_api_failure::refund_wallet_after_api_failure;
|
||||
use crate::http_server::endpoints::generate::common::payments_error_test::payments_error_test;
|
||||
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
|
||||
use crate::state::server_state::ServerState;
|
||||
@@ -20,7 +21,6 @@ use mysql_queries::queries::generic_inference::worldlabs::insert_generic_inferen
|
||||
use mysql_queries::queries::idepotency_tokens::insert_idempotency_token::insert_idempotency_token;
|
||||
use mysql_queries::queries::prompt_context_items::insert_batch_prompt_context_items::{insert_batch_prompt_context_items, InsertBatchArgs, PromptContextItem};
|
||||
use mysql_queries::queries::prompts::insert_prompt::{insert_prompt, InsertPromptArgs};
|
||||
use mysql_queries::queries::wallets::refund::try_to_refund_ledger_entry::{try_to_refund_ledger_entry, WalletRefundOutcome};
|
||||
use sqlx::Acquire;
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use world_labs_api::api::api_types::world_labs_model::WorldLabsModel;
|
||||
@@ -155,7 +155,7 @@ pub async fn generate_worldlabs_marble_0p1_plus_splat_handler(
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
warn!("World Labs generate_world error: {:?}", err);
|
||||
refund_after_api_failure(&wallet_deduction.ledger_entry_token, &mut mysql_connection).await;
|
||||
refund_wallet_after_api_failure(&wallet_deduction.ledger_entry_token, &mut mysql_connection).await;
|
||||
return Err(CommonWebError::ServerError);
|
||||
}
|
||||
};
|
||||
@@ -247,50 +247,3 @@ pub async fn generate_worldlabs_marble_0p1_plus_splat_handler(
|
||||
inference_job_token: job_token,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn refund_after_api_failure(
|
||||
ledger_entry_token: &tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken,
|
||||
connection: &mut sqlx::pool::PoolConnection<sqlx::MySql>,
|
||||
) {
|
||||
let mut transaction = match connection.begin().await {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to begin refund transaction after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match try_to_refund_ledger_entry(ledger_entry_token, &mut transaction).await {
|
||||
Ok(WalletRefundOutcome::Refunded(summary)) => {
|
||||
info!(
|
||||
"Refunded {} credits after API failure (ledger {} → refund ledger {}).",
|
||||
summary.refund_amount,
|
||||
ledger_entry_token.as_str(),
|
||||
summary.refund_ledger_entry_token.as_str(),
|
||||
);
|
||||
if let Err(err) = transaction.commit().await {
|
||||
error!(
|
||||
"Failed to commit refund after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(WalletRefundOutcome::AlreadyRefunded) => {
|
||||
info!(
|
||||
"Ledger entry {} was already refunded; no action needed.",
|
||||
ledger_entry_token.as_str()
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to refund ledger entry {} after API failure: {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-49
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::billing::wallets::attempt_wallet_deduction::attempt_wallet_deduction_else_common_web_error;
|
||||
use crate::http_server::common_responses::common_web_error::CommonWebError;
|
||||
use crate::http_server::endpoint_helpers::refund_wallet_after_api_failure::refund_wallet_after_api_failure;
|
||||
use crate::http_server::endpoints::generate::common::payments_error_test::payments_error_test;
|
||||
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
|
||||
use crate::state::server_state::ServerState;
|
||||
@@ -29,7 +30,6 @@ use mysql_queries::queries::prompt_context_items::insert_batch_prompt_context_it
|
||||
insert_batch_prompt_context_items, InsertBatchArgs, PromptContextItem,
|
||||
};
|
||||
use mysql_queries::queries::prompts::insert_prompt::{insert_prompt, InsertPromptArgs};
|
||||
use mysql_queries::queries::wallets::refund::try_to_refund_ledger_entry::{try_to_refund_ledger_entry, WalletRefundOutcome};
|
||||
use seedance2pro::creds::seedance2pro_session::Seedance2ProSession;
|
||||
use seedance2pro::requests::generate_video::generate_video::{
|
||||
generate_video, BatchCount, GenerateVideoArgs, Resolution,
|
||||
@@ -221,7 +221,7 @@ pub async fn seedance_2p0_multi_function_video_gen_handler(
|
||||
Ok(resp) => resp,
|
||||
Err(err) => {
|
||||
warn!("Error calling seedance2pro generate_video: {:?}", err);
|
||||
refund_after_api_failure(&deduction_result.ledger_entry_token, &mut mysql_connection).await;
|
||||
refund_wallet_after_api_failure(&deduction_result.ledger_entry_token, &mut mysql_connection).await;
|
||||
|
||||
// TODO: We need to start returning robust failure messages to the caller.
|
||||
return Err(CommonWebError::ServerError);
|
||||
@@ -375,53 +375,6 @@ pub async fn seedance_2p0_multi_function_video_gen_handler(
|
||||
}))
|
||||
}
|
||||
|
||||
async fn refund_after_api_failure(
|
||||
ledger_entry_token: &tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken,
|
||||
connection: &mut sqlx::pool::PoolConnection<sqlx::MySql>,
|
||||
) {
|
||||
let mut transaction = match connection.begin().await {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to begin refund transaction after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match try_to_refund_ledger_entry(ledger_entry_token, &mut transaction).await {
|
||||
Ok(WalletRefundOutcome::Refunded(summary)) => {
|
||||
info!(
|
||||
"Refunded {} credits after API failure (ledger {} → refund ledger {}).",
|
||||
summary.refund_amount,
|
||||
ledger_entry_token.as_str(),
|
||||
summary.refund_ledger_entry_token.as_str(),
|
||||
);
|
||||
if let Err(err) = transaction.commit().await {
|
||||
error!(
|
||||
"Failed to commit refund after API failure (ledger {}): {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(WalletRefundOutcome::AlreadyRefunded) => {
|
||||
info!(
|
||||
"Ledger entry {} was already refunded; no action needed.",
|
||||
ledger_entry_token.as_str()
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to refund ledger entry {} after API failure: {:?}",
|
||||
ledger_entry_token.as_str(), err
|
||||
);
|
||||
let _ = transaction.rollback().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn upload_to_seedance2pro(
|
||||
session: &Seedance2ProSession,
|
||||
our_cdn_url: &str,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod common_requests;
|
||||
pub mod common_responses;
|
||||
pub mod endpoint_helpers;
|
||||
pub mod cookies;
|
||||
pub mod deprecated_endpoints;
|
||||
pub mod endpoints;
|
||||
|
||||
Reference in new issue
Block a user