From 5b5dc68f581c3a86a70d7464867880d446cb1aed Mon Sep 17 00:00:00 2001 From: "Brandon T. Kowalski" Date: Mon, 12 Jan 2026 19:37:36 -0500 Subject: [PATCH 1/5] Added `updated_after` query parameter for platform and rom endpoints. --- backend/endpoints/platform.py | 16 +++++++++++++--- backend/endpoints/rom.py | 5 +++++ backend/handler/database/platforms_handler.py | 4 ++++ backend/handler/database/roms_handler.py | 5 +++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/backend/endpoints/platform.py b/backend/endpoints/platform.py index c8da143ca..e063f9371 100644 --- a/backend/endpoints/platform.py +++ b/backend/endpoints/platform.py @@ -1,8 +1,9 @@ +from datetime import datetime from typing import Annotated from fastapi import Body from fastapi import Path as PathVar -from fastapi import Request, status +from fastapi import Query, Request, status from decorators.auth import protected_route from endpoints.responses.platform import PlatformSchema @@ -48,11 +49,20 @@ async def add_platform( @protected_route(router.get, "", [Scope.PLATFORMS_READ]) -def get_platforms(request: Request) -> list[PlatformSchema]: +def get_platforms( + request: Request, + updated_after: Annotated[ + datetime | None, + Query( + description="Filter platforms updated after this datetime (ISO 8601 format)." + ), + ] = None, +) -> list[PlatformSchema]: """Retrieve platforms.""" return [ - PlatformSchema.model_validate(p) for p in db_platform_handler.get_platforms() + PlatformSchema.model_validate(p) + for p in db_platform_handler.get_platforms(updated_after=updated_after) ] diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index 4f5e963bd..07660ea79 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -405,6 +405,10 @@ def get_roms( str, Query(description="Order direction, either 'asc' or 'desc'."), ] = "asc", + updated_after: Annotated[ + datetime | None, + Query(description="Filter roms updated after this datetime (ISO 8601 format)."), + ] = None, ) -> CustomLimitOffsetPage[SimpleRomSchema]: """Retrieve roms.""" query, order_by_attr = db_rom_handler.get_roms_query( @@ -450,6 +454,7 @@ def get_roms( statuses_logic=statuses_logic, player_counts_logic=player_counts_logic, group_by_meta_id=group_by_meta_id, + updated_after=updated_after, ) # Get the char index for the roms diff --git a/backend/handler/database/platforms_handler.py b/backend/handler/database/platforms_handler.py index 16709413c..f53ba7ffd 100644 --- a/backend/handler/database/platforms_handler.py +++ b/backend/handler/database/platforms_handler.py @@ -1,5 +1,6 @@ import functools from collections.abc import Sequence +from datetime import datetime from sqlalchemy import delete, or_, select, update from sqlalchemy.orm import Query, Session, selectinload @@ -65,9 +66,12 @@ class DBPlatformsHandler(DBBaseHandler): @with_firmware def get_platforms( self, + updated_after: datetime | None = None, query: Query = None, # type: ignore session: Session = None, # type: ignore ) -> Sequence[Platform]: + if updated_after: + query = query.filter(Platform.updated_at > updated_after) return session.scalars(query.order_by(Platform.name.asc())).unique().all() @begin_session diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index 9078f7fce..fcaea6350 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -1,5 +1,6 @@ import functools from collections.abc import Iterable, Sequence +from datetime import datetime from typing import Any from sqlalchemy import ( @@ -510,6 +511,7 @@ class DBRomsHandler(DBBaseHandler): statuses_logic: str = "any", player_counts_logic: str = "any", user_id: int | None = None, + updated_after: datetime | None = None, session: Session = None, # type: ignore ) -> Query[Rom]: from handler.scan_handler import MetadataSource @@ -563,6 +565,9 @@ class DBRomsHandler(DBBaseHandler): if verified: query = self.filter_by_verified(query) + if updated_after: + query = query.filter(Rom.updated_at > updated_after) + # BEWARE YE WHO ENTERS HERE 💀 if group_by_meta_id: # Convert NULL is_main_sibling to 0 (false) so it sorts after true values From ff377fcd6891e233c0b4d035f5763a5542cf5933 Mon Sep 17 00:00:00 2001 From: "Brandon T. Kowalski" Date: Mon, 12 Jan 2026 19:43:59 -0500 Subject: [PATCH 2/5] Add migration for `updated_at` index on `roms` and `platforms` tables. --- .../versions/0064_add_updated_at_indexes.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 backend/alembic/versions/0064_add_updated_at_indexes.py diff --git a/backend/alembic/versions/0064_add_updated_at_indexes.py b/backend/alembic/versions/0064_add_updated_at_indexes.py new file mode 100644 index 000000000..999438f80 --- /dev/null +++ b/backend/alembic/versions/0064_add_updated_at_indexes.py @@ -0,0 +1,31 @@ +"""Add indexes on updated_at for roms and platforms tables + +Revision ID: 0064_add_updated_at_indexes +Revises: 0063_roms_metadata_player_count +Create Date: 2026-01-12 + +""" + +from alembic import op + +# revision identifiers, used by Alembic. +revision = "0064_add_updated_at_indexes" +down_revision = "0063_roms_metadata_player_count" +branch_labels = None +depends_on = None + + +def upgrade(): + with op.batch_alter_table("roms", schema=None) as batch_op: + batch_op.create_index("ix_roms_updated_at", ["updated_at"], unique=False) + + with op.batch_alter_table("platforms", schema=None) as batch_op: + batch_op.create_index("ix_platforms_updated_at", ["updated_at"], unique=False) + + +def downgrade(): + with op.batch_alter_table("roms", schema=None) as batch_op: + batch_op.drop_index("ix_roms_updated_at") + + with op.batch_alter_table("platforms", schema=None) as batch_op: + batch_op.drop_index("ix_platforms_updated_at") From eebcf1cf62c4551a1320cac8bcb854a802ab6851 Mon Sep 17 00:00:00 2001 From: "Brandon T. Kowalski" Date: Mon, 12 Jan 2026 20:01:49 -0500 Subject: [PATCH 3/5] Update backend/endpoints/rom.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- backend/endpoints/rom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index 07660ea79..9be948da3 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -407,7 +407,7 @@ def get_roms( ] = "asc", updated_after: Annotated[ datetime | None, - Query(description="Filter roms updated after this datetime (ISO 8601 format)."), + Query(description="Filter roms updated after this datetime (ISO 8601 format with timezone information)."), ] = None, ) -> CustomLimitOffsetPage[SimpleRomSchema]: """Retrieve roms.""" From 8ba5ff38ed6f94cc952d8d255da30a7585a5b79f Mon Sep 17 00:00:00 2001 From: "Brandon T. Kowalski" Date: Mon, 12 Jan 2026 20:01:56 -0500 Subject: [PATCH 4/5] Update backend/endpoints/platform.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- backend/endpoints/platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/endpoints/platform.py b/backend/endpoints/platform.py index e063f9371..9f77f766d 100644 --- a/backend/endpoints/platform.py +++ b/backend/endpoints/platform.py @@ -54,7 +54,7 @@ def get_platforms( updated_after: Annotated[ datetime | None, Query( - description="Filter platforms updated after this datetime (ISO 8601 format)." + description="Filter platforms updated after this datetime (ISO 8601 format with timezone information)." ), ] = None, ) -> list[PlatformSchema]: From 0a584b68aeffe5beba421542343dfce0bd3082ea Mon Sep 17 00:00:00 2001 From: "Brandon T. Kowalski" Date: Tue, 13 Jan 2026 08:41:05 -0500 Subject: [PATCH 5/5] Fixing the clanker's formatting. --- backend/endpoints/rom.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index 9be948da3..c4614b4da 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -407,7 +407,9 @@ def get_roms( ] = "asc", updated_after: Annotated[ datetime | None, - Query(description="Filter roms updated after this datetime (ISO 8601 format with timezone information)."), + Query( + description="Filter roms updated after this datetime (ISO 8601 format with timezone information)." + ), ] = None, ) -> CustomLimitOffsetPage[SimpleRomSchema]: """Retrieve roms."""