From 71dee4de40b8f33808677b2cbc1c6ecb156af78d Mon Sep 17 00:00:00 2001 From: aecsocket Date: Thu, 21 May 2026 21:21:54 +0100 Subject: [PATCH] Add modpacks with external files filter to moderation queue (#6155) * simplify query * make it a tristate * external deps count --- ...67c75d30056143c0bcabdbd74bb4c7b442082.json | 31 ++++++++++ ...c43e1e5d0a532171b5de7b9086ae7376f1482.json | 24 -------- .../src/routes/internal/moderation/mod.rs | 57 ++++++++++++++++--- apps/labrinth/src/routes/v2/moderation.rs | 1 + 4 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 apps/labrinth/.sqlx/query-119a59fcf4bb2f19f89002c712a67c75d30056143c0bcabdbd74bb4c7b442082.json delete mode 100644 apps/labrinth/.sqlx/query-ec1f08768071d55613b0b69b3eac43e1e5d0a532171b5de7b9086ae7376f1482.json diff --git a/apps/labrinth/.sqlx/query-119a59fcf4bb2f19f89002c712a67c75d30056143c0bcabdbd74bb4c7b442082.json b/apps/labrinth/.sqlx/query-119a59fcf4bb2f19f89002c712a67c75d30056143c0bcabdbd74bb4c7b442082.json new file mode 100644 index 000000000..fcd5b34f1 --- /dev/null +++ b/apps/labrinth/.sqlx/query-119a59fcf4bb2f19f89002c712a67c75d30056143c0bcabdbd74bb4c7b442082.json @@ -0,0 +1,31 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n id,\n external_dependencies_count as \"external_dependencies_count!\"\n FROM (\n SELECT DISTINCT ON (m.id)\n m.id,\n m.queued,\n (\n SELECT COUNT(*)\n FROM versions v\n INNER JOIN dependencies d ON d.dependent_id = v.id\n WHERE v.mod_id = m.id\n AND d.dependency_file_name IS NOT NULL\n ) external_dependencies_count\n FROM mods m\n\n /* -- Temporarily, don't exclude projects in tech rev q\n\n -- exclude projects in tech review queue\n LEFT JOIN delphi_issue_details_with_statuses didws\n ON didws.project_id = m.id AND didws.status = 'pending'\n */\n\n WHERE\n m.status = $1\n /* AND didws.status IS NULL */ -- Temporarily don't exclude\n\n GROUP BY m.id\n ) t\n WHERE\n ($4::boolean IS NULL OR (external_dependencies_count > 0) = $4)\n ORDER BY queued ASC\n OFFSET $3\n LIMIT $2\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "external_dependencies_count!", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Text", + "Int8", + "Int8", + "Bool" + ] + }, + "nullable": [ + false, + null + ] + }, + "hash": "119a59fcf4bb2f19f89002c712a67c75d30056143c0bcabdbd74bb4c7b442082" +} diff --git a/apps/labrinth/.sqlx/query-ec1f08768071d55613b0b69b3eac43e1e5d0a532171b5de7b9086ae7376f1482.json b/apps/labrinth/.sqlx/query-ec1f08768071d55613b0b69b3eac43e1e5d0a532171b5de7b9086ae7376f1482.json deleted file mode 100644 index 1f0b3d1ef..000000000 --- a/apps/labrinth/.sqlx/query-ec1f08768071d55613b0b69b3eac43e1e5d0a532171b5de7b9086ae7376f1482.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT id\n FROM (\n SELECT DISTINCT ON (m.id)\n m.id,\n m.queued\n FROM mods m\n\n /* -- Temporarily, don't exclude projects in tech rev q\n\n -- exclude projects in tech review queue\n LEFT JOIN delphi_issue_details_with_statuses didws\n ON didws.project_id = m.id AND didws.status = 'pending'\n */\n\n WHERE\n m.status = $1\n /* AND didws.status IS NULL */ -- Temporarily don't exclude\n\n GROUP BY m.id\n ) t\n ORDER BY queued ASC\n OFFSET $3\n LIMIT $2\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Text", - "Int8", - "Int8" - ] - }, - "nullable": [ - false - ] - }, - "hash": "ec1f08768071d55613b0b69b3eac43e1e5d0a532171b5de7b9086ae7376f1482" -} diff --git a/apps/labrinth/src/routes/internal/moderation/mod.rs b/apps/labrinth/src/routes/internal/moderation/mod.rs index c3b77bcbe..ddcc775a7 100644 --- a/apps/labrinth/src/routes/internal/moderation/mod.rs +++ b/apps/labrinth/src/routes/internal/moderation/mod.rs @@ -53,6 +53,9 @@ pub struct ProjectsRequestOptions { /// How many projects to skip. #[serde(default)] pub offset: u32, + /// Whether to filter by modpacks that have external dependencies. + #[serde(default)] + pub has_external_dependencies: Option, } fn default_count() -> u16 { @@ -68,6 +71,8 @@ pub struct FetchedProject { pub project: Project, /// Who owns the project. pub ownership: Ownership, + /// How many external file dependencies the project has. + pub external_dependencies_count: i64, } /// Fetched information on who owns a project. @@ -190,13 +195,22 @@ pub async fn get_projects_internal( use futures::stream::TryStreamExt; - let project_ids = sqlx::query!( - " - SELECT id + let project_rows = sqlx::query!( + r#" + SELECT + id, + external_dependencies_count as "external_dependencies_count!" FROM ( SELECT DISTINCT ON (m.id) m.id, - m.queued + m.queued, + ( + SELECT COUNT(*) + FROM versions v + INNER JOIN dependencies d ON d.dependent_id = v.id + WHERE v.mod_id = m.id + AND d.dependency_file_name IS NOT NULL + ) external_dependencies_count FROM mods m /* -- Temporarily, don't exclude projects in tech rev q @@ -212,20 +226,36 @@ pub async fn get_projects_internal( GROUP BY m.id ) t + WHERE + ($4::boolean IS NULL OR (external_dependencies_count > 0) = $4) ORDER BY queued ASC OFFSET $3 LIMIT $2 - ", + "#, ProjectStatus::Processing.as_str(), request_opts.count as i64, - request_opts.offset as i64 + request_opts.offset as i64, + request_opts.has_external_dependencies, ) .fetch(&**pool) - .map_ok(|m| database::models::DBProjectId(m.id)) - .try_collect::>() + .try_collect::>() .await .wrap_internal_err("failed to fetch projects awaiting review")?; + let project_ids = project_rows + .iter() + .map(|m| database::models::DBProjectId(m.id)) + .collect::>(); + let project_metadata = project_rows + .into_iter() + .map(|m| { + ( + database::models::DBProjectId(m.id), + m.external_dependencies_count, + ) + }) + .collect::>(); + let projects = database::DBProject::get_many_ids(&project_ids, &**pool, &redis) .await @@ -240,7 +270,16 @@ pub async fn get_projects_internal( let map_project = |(project, ownership): (Project, Ownership)| -> FetchedProject { - FetchedProject { ownership, project } + let external_dependencies_count = project_metadata + .get(&database::models::DBProjectId(project.id.0 as i64)) + .copied() + .unwrap_or_default(); + + FetchedProject { + ownership, + project, + external_dependencies_count, + } }; let projects = projects diff --git a/apps/labrinth/src/routes/v2/moderation.rs b/apps/labrinth/src/routes/v2/moderation.rs index 8cba1ccbd..b79a6b7bd 100644 --- a/apps/labrinth/src/routes/v2/moderation.rs +++ b/apps/labrinth/src/routes/v2/moderation.rs @@ -61,6 +61,7 @@ pub async fn get_projects( web::Query(internal::moderation::ProjectsRequestOptions { count: count.count, offset: 0, + has_external_dependencies: None, }), session_queue, )