Skip to content

fix: optimize toggle_favourite endpoint performance#1094

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

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

Conversation

@harsh1519
Copy link

@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

  • Performance Improvements

    • Faster, more direct image lookup to speed up image-related operations and reduce delays after 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.

✏️ Tip: You can customize this high-level summary in your review settings.

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

coderabbitai bot commented Jan 27, 2026

📝 Walkthrough

Walkthrough

Adds db_get_image_by_id(image_id: str) -> Optional[dict] to fetch a single image record (with parsed JSON metadata and boolean fields) 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 DB connection, SELECTs a single image by id, parses metadata JSON into a dict (or empty dict on error), 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 changed toggle_favourite to fetch the updated image via db_get_image_by_id(image_id) after toggling; returns 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

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 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately summarizes the main change: optimizing the toggle_favourite endpoint by replacing an O(n) database scan with a direct ID-based lookup for better performance.

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

✨ Finishing touches
  • 📝 Generate docstrings

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
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