Skip to content

fix: optimize toggle_favourite endpoint performance#1094

Open
harsh1519 wants to merge 4 commits intoAOSSIE-Org:mainfrom
harsh1519:fix/toggle-favourite-performance
Open

fix: optimize toggle_favourite endpoint performance#1094
harsh1519 wants to merge 4 commits intoAOSSIE-Org:mainfrom
harsh1519:fix/toggle-favourite-performance

Conversation

@harsh1519
Copy link
Copy Markdown

@harsh1519 harsh1519 commented Jan 27, 2026

Related to #977

The /toggle-favourite endpoint previously fetched all images from the database
to determine the favourite status of a single image, causing O(n) complexity
and unnecessary memory usage.

This PR updates the route to fetch only the specific image by ID and return
the updated favourite status.

Summary by CodeRabbit

  • New Features

    • UI now reflects image updates immediately after actions like toggling favorites.
  • Performance Improvements

    • Faster, more direct image lookup to reduce delays after image actions.
  • Bug Fixes

    • More reliable favorite-toggle behavior with clearer "not found" feedback when an image is missing after toggling and preserved HTTP error handling so errors surface correctly.

@github-actions github-actions bot added backend enhancement New feature or request labels Jan 27, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 777e4d93-6c5d-4088-b866-2a7896b518d6

📥 Commits

Reviewing files that changed from the base of the PR and between 668bd12 and ceec563.

📒 Files selected for processing (1)
  • backend/app/database/images.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/app/database/images.py

Walkthrough

Adds a new DB accessor db_get_image_by_id(image_id: str) -> Optional[dict] that returns a single image record with parsed JSON metadata and boolean flags, and updates the toggle_favourite route to use this DB lookup after toggling instead of scanning all images.

Changes

Cohort / File(s) Summary
Database Function Addition
backend/app/database/images.py
Added db_get_image_by_id(image_id: str) -> Optional[dict] that opens a SQLite connection, SELECTs a single image by id, parses metadata JSON into a dict (or {} on error/empty), converts isTagged/isFavourite to booleans, returns None if not found, and ensures connection close in finally.
Route Update
backend/app/routes/images.py
Imported db_get_image_by_id and updated toggle_favourite to call it after performing the toggle UPDATE; returns the single updated image (200) or 404 if missing post-toggle; preserves HTTPException pass-through and raises 500 for other exceptions.
sequenceDiagram
    participant C as Client
    participant R as API Route (toggle_favourite)
    participant DB as Database
    Note over R,DB: Toggle favourite then fetch updated record
    C->>R: POST /images/{id}/toggle_favourite
    R->>DB: UPDATE images SET isFavourite = NOT isFavourite WHERE id = {id}
    DB-->>R: OK (rows affected)
    R->>DB: SELECT id, path, folder_id, thumbnailPath, metadata, isTagged, isFavourite FROM images WHERE id = {id}
    DB-->>R: image row or NULL
    alt image found
        R-->>C: 200 OK with updated image
    else not found
        R-->>C: 404 Image not found after toggle
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

Python, Documentation

Poem

🐰
I hopped to rows with a curious twitch,
Toggled a star and fetched just one stitch.
No wide scans through meadow or dew,
One small query, and the picture grew. ✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: optimize toggle_favourite endpoint performance' directly and concisely summarizes the main change: optimizing the toggle_favourite endpoint by reducing database query complexity from O(n) to O(1).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/app/routes/images.py (1)

99-125: Preserve intended 404s by not swallowing HTTPException.
The broad except Exception will catch the 404 you raise and return a 500 instead.

🐛 Proposed fix
     try:
         success = db_toggle_image_favourite_status(image_id)
         if not success:
             raise HTTPException(
                 status_code=404, detail="Image not found or failed to toggle"
             )
         # Fetch updated status to return
         image = db_get_image_by_id(image_id)
         if not image:
             raise HTTPException(
                 status_code=404, detail="Image not found after toggle"
             )
         return {
             "success": True,
             "image_id": image_id,
             "isFavourite": image.get("isFavourite", False),
         }
 
-    except Exception as e:
+    except HTTPException:
+        raise
+    except Exception as e:
         logger.error(f"error in /toggle-favourite route: {e}")
         raise HTTPException(status_code=500, detail=f"Internal server error: {e}")
🤖 Fix all issues with AI agents
In `@backend/app/database/images.py`:
- Around line 425-446: The db_get_image_by_id function currently calls
json.loads(row[4]) which can raise json.JSONDecodeError and cause unrelated
endpoints to 500; wrap the metadata parsing in a try/except that catches
json.JSONDecodeError (or Exception) and falls back to an empty dict for the
"metadata" field so the function returns normally; update the code around
json.loads(row[4]) in db_get_image_by_id to perform the safe parse with fallback
and keep other returned fields unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant