mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 12:05:53 +00:00
feat: specify users to remove notifications from
This commit is contained in:
+4
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT id\n FROM notifications\n WHERE body @> $1::jsonb\n ",
|
||||
"query": "\n SELECT id\n FROM notifications\n WHERE body @> $1::jsonb\n AND user_id = ANY($2::bigint[])\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -11,12 +11,13 @@
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Jsonb"
|
||||
"Jsonb",
|
||||
"Int8Array"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "00d809d1dc9dd1eb2c49ebaac2387f82c5730d835ae1c52d5df23b5f09cd1925"
|
||||
"hash": "147f31c59219c5485531914897618427375b203777a68fd6ece1a50feaf41df9"
|
||||
}
|
||||
@@ -599,16 +599,21 @@ impl DBNotification {
|
||||
|
||||
pub async fn remove_many_matching_body(
|
||||
body_filter: &serde_json::Value,
|
||||
users: &[DBUserId],
|
||||
transaction: &mut PgTransaction<'_>,
|
||||
redis: &RedisPool,
|
||||
) -> Result<usize, DatabaseError> {
|
||||
let user_ids = users.iter().map(|x| x.0).collect::<Vec<i64>>();
|
||||
|
||||
let ids = sqlx::query!(
|
||||
"
|
||||
SELECT id
|
||||
FROM notifications
|
||||
WHERE body @> $1::jsonb
|
||||
AND user_id = ANY($2::bigint[])
|
||||
",
|
||||
body_filter
|
||||
body_filter,
|
||||
&user_ids
|
||||
)
|
||||
.fetch(&mut *transaction)
|
||||
.map_ok(|x| DBNotificationId(x.id))
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::database::models::user_item::DBUser;
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::models::users::Role;
|
||||
use crate::models::v3::notifications::{
|
||||
NotificationBody, NotificationDeliveryStatus, NotificationType,
|
||||
NotificationBody, NotificationDeliveryStatus,
|
||||
};
|
||||
use crate::models::v3::pats::Scopes;
|
||||
use crate::queue::email::EmailQueue;
|
||||
@@ -160,18 +160,45 @@ pub async fn create_direct_email(
|
||||
Ok(web::Json(failed).customize().with_status(status))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct NotificationFilter {
|
||||
pub user_ids: Vec<UserId>,
|
||||
#[serde(flatten)]
|
||||
pub body: serde_json::Map<String, serde_json::Value>,
|
||||
}
|
||||
|
||||
#[delete("external_notifications", guard = "external_notification_key_guard")]
|
||||
pub async fn remove(
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<RedisPool>,
|
||||
notification_filter: web::Json<serde_json::Value>,
|
||||
notification_filter: web::Json<NotificationFilter>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let NotificationFilter { user_ids, body } =
|
||||
notification_filter.into_inner();
|
||||
|
||||
if user_ids.is_empty() {
|
||||
return Err(ApiError::Request(eyre!(
|
||||
"at least one user must be provided to remove notifications from"
|
||||
)));
|
||||
}
|
||||
|
||||
if body.is_empty() {
|
||||
return Err(ApiError::Request(eyre!(
|
||||
"at least one `body` field must be provided to match notifications"
|
||||
)));
|
||||
}
|
||||
|
||||
let filters = serde_json::Value::Object(body);
|
||||
|
||||
let user_ids = user_ids
|
||||
.into_iter()
|
||||
.map(|x| DBUserId(x.0 as i64))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut txn = pool.begin().await?;
|
||||
|
||||
DBNotification::remove_many_matching_body(
|
||||
¬ification_filter,
|
||||
&mut txn,
|
||||
&redis,
|
||||
&filters, &user_ids, &mut txn, &redis,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user