add: automatically stop all user ads when user cannot afford transfer

This commit is contained in:
trisua 2025-08-11 20:44:16 -04:00
parent 2cb7d08ddc
commit 59bccd9474
4 changed files with 70 additions and 26 deletions

View file

@ -56,6 +56,30 @@ impl DataManager {
Ok(res.unwrap())
}
/// Disable all ads by the given user.
///
/// # Arguments
/// * `id` - the ID of the user to kill ads from
pub async fn stop_all_ads_by_user(&self, id: usize) -> Result<Vec<UserAd>> {
let conn = match self.0.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = query_rows!(
&conn,
"UPDATE ads SET is_running = 0 WHERE owner = $1",
&[&(id as i64)],
|x| { Self::get_ad_from_row(x) }
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
Ok(res.unwrap())
}
/// Create a new ad in the database.
///
/// # Arguments
@ -161,7 +185,7 @@ impl DataManager {
const MINIMUM_DELTA_FOR_CHARGE: usize = 604_800_000; // 7 days
/// The amount charged to a [`UserAd`] owner each day the ad is running (and is pulled from the pool).
pub const AD_RUN_CHARGE: i32 = 50;
pub const AD_RUN_CHARGE: i32 = 25;
/// The amount charged to a [`UserAd`] owner each time the ad is clicked.
pub const AD_CLICK_CHARGE: i32 = 2;
@ -173,17 +197,23 @@ impl DataManager {
let delta = now - ad.last_charge_time;
if delta >= Self::MINIMUM_DELTA_FOR_CHARGE {
self.create_transfer(
&mut CoinTransfer::new(
ad.owner,
self.0.0.system_user,
Self::AD_RUN_CHARGE,
CoinTransferMethod::Transfer,
CoinTransferSource::AdCharge,
),
true,
)
.await?;
if let Err(e) = self
.create_transfer(
&mut CoinTransfer::new(
ad.owner,
self.0.0.system_user,
Self::AD_RUN_CHARGE,
CoinTransferMethod::Transfer,
CoinTransferSource::AdCharge,
),
true,
)
.await
{
// boo user cannot afford to keep running their ads
self.stop_all_ads_by_user(ad.owner).await?;
return Err(e);
};
self.update_ad_last_charge_time(ad.id, now as i64).await?;
}
@ -212,17 +242,22 @@ impl DataManager {
}
// create click transfer
self.create_transfer(
&mut CoinTransfer::new(
ad.owner,
host,
Self::AD_CLICK_CHARGE,
CoinTransferMethod::Transfer,
CoinTransferSource::AdClick,
),
true,
)
.await?;
if let Err(e) = self
.create_transfer(
&mut CoinTransfer::new(
ad.owner,
host,
Self::AD_CLICK_CHARGE,
CoinTransferMethod::Transfer,
CoinTransferSource::AdClick,
),
true,
)
.await
{
self.stop_all_ads_by_user(ad.owner).await?;
return Err(e);
}
// return
Ok(ad.target)