Compare commits

...
Author SHA1 Message Date
Calum H. (IMB11) cb181a04e0 fix: introduce badge 2026-05-31 00:49:48 +01:00
5 changed files with 222 additions and 7 deletions
@@ -0,0 +1,173 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT id, email,\n avatar_url, raw_avatar_url, username, bio,\n created, role, badges,\n (\n SELECT MAX(campaign_donations.donated_at)\n FROM campaign_donations\n WHERE campaign_donations.user_id = users.id\n AND campaign_donations.amount_usd >= 5\n ) AS campaign_pride_26,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id, allow_friend_requests, is_subscribed_to_newsletter\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "email",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "avatar_url",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "raw_avatar_url",
"type_info": "Text"
},
{
"ordinal": 4,
"name": "username",
"type_info": "Varchar"
},
{
"ordinal": 5,
"name": "bio",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "created",
"type_info": "Timestamptz"
},
{
"ordinal": 7,
"name": "role",
"type_info": "Varchar"
},
{
"ordinal": 8,
"name": "badges",
"type_info": "Int8"
},
{
"ordinal": 9,
"name": "campaign_pride_26",
"type_info": "Timestamptz"
},
{
"ordinal": 10,
"name": "github_id",
"type_info": "Int8"
},
{
"ordinal": 11,
"name": "discord_id",
"type_info": "Int8"
},
{
"ordinal": 12,
"name": "gitlab_id",
"type_info": "Int8"
},
{
"ordinal": 13,
"name": "google_id",
"type_info": "Varchar"
},
{
"ordinal": 14,
"name": "steam_id",
"type_info": "Int8"
},
{
"ordinal": 15,
"name": "microsoft_id",
"type_info": "Varchar"
},
{
"ordinal": 16,
"name": "email_verified",
"type_info": "Bool"
},
{
"ordinal": 17,
"name": "password",
"type_info": "Text"
},
{
"ordinal": 18,
"name": "totp_secret",
"type_info": "Varchar"
},
{
"ordinal": 19,
"name": "paypal_id",
"type_info": "Text"
},
{
"ordinal": 20,
"name": "paypal_country",
"type_info": "Text"
},
{
"ordinal": 21,
"name": "paypal_email",
"type_info": "Text"
},
{
"ordinal": 22,
"name": "venmo_handle",
"type_info": "Text"
},
{
"ordinal": 23,
"name": "stripe_customer_id",
"type_info": "Text"
},
{
"ordinal": 24,
"name": "allow_friend_requests",
"type_info": "Bool"
},
{
"ordinal": 25,
"name": "is_subscribed_to_newsletter",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Int8Array",
"TextArray"
]
},
"nullable": [
false,
true,
true,
true,
false,
true,
false,
false,
false,
null,
true,
true,
true,
true,
true,
true,
false,
true,
true,
true,
true,
true,
true,
true,
false,
false
]
},
"hash": "5ed1f07dfcb5590ac98594ac38a9d7894f83410fdd5d7061aa80885701f9f8dd"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE users\n SET badges = $1\n WHERE (id = $2)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8"
]
},
"nullable": []
},
"hash": "99a1f21d6c690e01a61747416e47c6fac2d6450928532b3346d34f0375bd35f0"
}
@@ -186,7 +186,7 @@ impl DBUser {
SELECT MAX(campaign_donations.donated_at)
FROM campaign_donations
WHERE campaign_donations.user_id = users.id
AND campaign_donations.amount_usd > 5
AND campaign_donations.amount_usd >= 5
) AS campaign_pride_26,
github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,
email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,
+1
View File
@@ -19,6 +19,7 @@ bitflags::bitflags! {
const CONTRIBUTOR = 1 << 5;
const TRANSLATOR = 1 << 6;
const AFFILIATE = 1 << 7;
const PRIDE_2026 = 1 << 8;
}
}
+32 -6
View File
@@ -18,7 +18,7 @@ use crate::{
redis::RedisPool,
},
env::ENV,
models::payouts::TremendousForexResponse,
models::{payouts::TremendousForexResponse, users::Badges},
queue::payouts::PayoutsQueue,
routes::ApiError,
util::{error::Context, http::HttpClient, tiltify::TiltifyClient},
@@ -179,7 +179,7 @@ pub async fn tiltify_webhook(
})?;
donation.user_id = Some(user.id);
eyre::Ok(username)
eyre::Ok((username, user.badges))
}
.await
.inspect_err(|err| {
@@ -203,7 +203,10 @@ pub async fn tiltify_webhook(
info!(
"Resolved donation from {} for US${}",
username.as_deref().unwrap_or("<unknown>"),
username
.as_ref()
.map(|(username, _)| username.as_str())
.unwrap_or("<unknown>"),
amount_usd
.map(|a| a.to_string())
.unwrap_or_else(|| "<unknown>".to_string())
@@ -223,15 +226,38 @@ pub async fn tiltify_webhook(
return Ok(());
}
if let (Some(user_id), Some((_, badges)), Some(amount_usd)) =
(donation.user_id, username.as_ref(), donation.amount_usd)
&& amount_usd >= Decimal::ONE
{
let badges = *badges | Badges::PRIDE_2026;
sqlx::query!(
"
UPDATE users
SET badges = $1
WHERE (id = $2)
",
badges.bits() as i64,
user_id.0,
)
.execute(&mut transaction)
.await
.wrap_internal_err("updating user campaign badge")?;
}
transaction
.commit()
.await
.wrap_internal_err("committing transaction")?;
if let Some(user_id) = donation.user_id {
DBUser::clear_caches(&[(user_id, username)], &redis)
.await
.wrap_internal_err("clearing user caches")?;
DBUser::clear_caches(
&[(user_id, username.map(|(username, _)| username))],
&redis,
)
.await
.wrap_internal_err("clearing user caches")?;
}
Ok(())