Fix updated field including deleted versions (#3643)

* Fix `updated` field including deleted versions

Four years ago, I created issue modrinth/labrinth#200. Today, while it adorns a different name (modrinth/code#2766), the issue remains the same. In celebration of Modrinth's oldest bug report, here is a fix.

Instead of having a separate `updated` field, it simply pulls the publish date of the most recent version. This should also allow the `updated` column on the `mods` table to be dropped at a later date, but I would rather get confirmation that it works before we go ahead with that.

Fixes #2766

* Update apps/labrinth/src/database/models/project_item.rs

Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>

---------

Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>
Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
This commit is contained in:
Emma Alexia 2025-05-12 14:19:30 -04:00 committed by GitHub
parent 9a6390bb4d
commit 863bf62f8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 31 deletions

View File

@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT m.id id, m.name name, m.summary summary, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.raw_icon_url raw_icon_url, m.description description, m.published published,\n m.updated updated, m.approved approved, m.queued, m.status status, m.requested_status requested_status,\n m.license_url license_url,\n m.team_id team_id, m.organization_id organization_id, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n m.webhook_sent, m.color,\n t.id thread_id, m.monetization_status monetization_status,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories\n FROM mods m\n INNER JOIN threads t ON t.mod_id = m.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n WHERE m.id = ANY($1) OR m.slug = ANY($2)\n GROUP BY t.id, m.id;\n ",
"query": "\n SELECT m.id id, m.name name, m.summary summary, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.raw_icon_url raw_icon_url, m.description description, m.published published,\n m.approved approved, m.queued, m.status status, m.requested_status requested_status,\n m.license_url license_url,\n m.team_id team_id, m.organization_id organization_id, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n m.webhook_sent, m.color,\n t.id thread_id, m.monetization_status monetization_status,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories\n FROM mods m\n INNER JOIN threads t ON t.mod_id = m.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n WHERE m.id = ANY($1) OR m.slug = ANY($2)\n GROUP BY t.id, m.id;\n ",
"describe": {
"columns": [
{
@ -50,91 +50,86 @@
},
{
"ordinal": 9,
"name": "updated",
"type_info": "Timestamptz"
},
{
"ordinal": 10,
"name": "approved",
"type_info": "Timestamptz"
},
{
"ordinal": 11,
"ordinal": 10,
"name": "queued",
"type_info": "Timestamptz"
},
{
"ordinal": 12,
"ordinal": 11,
"name": "status",
"type_info": "Varchar"
},
{
"ordinal": 13,
"ordinal": 12,
"name": "requested_status",
"type_info": "Varchar"
},
{
"ordinal": 14,
"ordinal": 13,
"name": "license_url",
"type_info": "Varchar"
},
{
"ordinal": 15,
"ordinal": 14,
"name": "team_id",
"type_info": "Int8"
},
{
"ordinal": 16,
"ordinal": 15,
"name": "organization_id",
"type_info": "Int8"
},
{
"ordinal": 17,
"ordinal": 16,
"name": "license",
"type_info": "Varchar"
},
{
"ordinal": 18,
"ordinal": 17,
"name": "slug",
"type_info": "Varchar"
},
{
"ordinal": 19,
"ordinal": 18,
"name": "moderation_message",
"type_info": "Varchar"
},
{
"ordinal": 20,
"ordinal": 19,
"name": "moderation_message_body",
"type_info": "Varchar"
},
{
"ordinal": 21,
"ordinal": 20,
"name": "webhook_sent",
"type_info": "Bool"
},
{
"ordinal": 22,
"ordinal": 21,
"name": "color",
"type_info": "Int4"
},
{
"ordinal": 23,
"ordinal": 22,
"name": "thread_id",
"type_info": "Int8"
},
{
"ordinal": 24,
"ordinal": 23,
"name": "monetization_status",
"type_info": "Varchar"
},
{
"ordinal": 25,
"ordinal": 24,
"name": "categories",
"type_info": "VarcharArray"
},
{
"ordinal": 26,
"ordinal": 25,
"name": "additional_categories",
"type_info": "VarcharArray"
}
@ -155,7 +150,6 @@
true,
false,
false,
false,
true,
true,
false,
@ -175,5 +169,5 @@
null
]
},
"hash": "c7c400d74c478b4194f478f6d732a92c0b9a72e1cb6147009018b2712398c24f"
"hash": "5f75c0c48083de27f853ee877aac070567fd2ed2be4a9a038821b790dd7cb763"
}

View File

@ -759,7 +759,7 @@ impl Project {
"
SELECT m.id id, m.name name, m.summary summary, m.downloads downloads, m.follows follows,
m.icon_url icon_url, m.raw_icon_url raw_icon_url, m.description description, m.published published,
m.updated updated, m.approved approved, m.queued, m.status status, m.requested_status requested_status,
m.approved approved, m.queued, m.status status, m.requested_status requested_status,
m.license_url license_url,
m.team_id team_id, m.organization_id organization_id, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,
m.webhook_sent, m.color,
@ -786,7 +786,9 @@ impl Project {
games,
loader_loader_field_ids,
} = loaders_ptypes_games.remove(&project_id).map(|x|x.1).unwrap_or_default();
// Each version is a tuple of (VersionId, DateTime<Utc>)
let mut versions = versions.remove(&project_id).map(|x| x.1).unwrap_or_default();
versions.sort_by(|a, b| a.1.cmp(&b.1));
let mut gallery = mods_gallery.remove(&project_id).map(|x| x.1).unwrap_or_default();
let urls = links.remove(&project_id).map(|x| x.1).unwrap_or_default();
let version_fields = version_fields.remove(&project_id).map(|x| x.1).unwrap_or_default();
@ -806,7 +808,7 @@ impl Project {
icon_url: m.icon_url.clone(),
raw_icon_url: m.raw_icon_url.clone(),
published: m.published,
updated: m.updated,
updated: versions.iter().map(|x| x.1).next_back().unwrap_or(m.published),
license_url: m.license_url.clone(),
status: ProjectStatus::from_string(
&m.status,
@ -833,11 +835,7 @@ impl Project {
additional_categories: m.additional_categories.unwrap_or_default(),
project_types,
games,
versions: {
// Each version is a tuple of (VersionId, DateTime<Utc>)
versions.sort_by(|a, b| a.1.cmp(&b.1));
versions.into_iter().map(|x| x.0).collect()
},
versions: versions.into_iter().map(|x| x.0).collect(),
gallery_items: {
gallery.sort_by(|a, b| a.ordering.cmp(&b.ordering));
gallery