Skip to content

feat(logic): Implement Smart Recommendation Engine & Data Pipeline Upgrades

AGHARAHIMOV AGHASALIM requested to merge feature/recommendation-engine into main

What does this MR do?

This MR implements the mandatory Recommendation Algorithm. Instead of using the generic TMDB recommendation endpoint, we built a custom "Content-Based Filtering" engine that analyzes the user's local history to suggest movies.

The Recommendation Algorithm (How it works)

The engine runs on a "Genre-Weighted" logic:

  1. Data Harvesting: We fetch all movies from the local database that the user has Liked OR Rated.
  2. Profiling: We calculate a "Score" for every genre found in these movies.
    • Like: +3 Points for that genre.
    • Rating: +[Star Rating] Points (e.g., 4.0 stars adds 4 points to the genre).
  3. Targeting: We identify the user's Top 2 Genres (e.g., Sci-Fi and Action).
  4. Discovery: We query the TMDB API using two strategies:
    • Strategy A (Comfort Zone): High-rated movies in the #1 Genre.
    • Strategy B (Discovery): Popular movies containing the #2 Genre.
  5. Filtering: We merge the lists, shuffle them, and remove any movies the user has already seen.

Key Technical Changes

  • Data Layer Upgrades:
    • Updated Movie models and Room Schema (Version 5) to store Genre IDs and User Ratings locally.
    • Updated MovieRepository to capture genres from the API.
    • Updated UserCollectionsRepository to implement the algorithm.
  • Pipeline Fixes:
    • Fixed a critical bug in ActionBottomSheet where genre data was lost during the UI handoff. Now passing data via Bundle ensures saved movies are valid for the algorithm.
  • UI Integration:
    • Updated HomeViewModel to prioritize Personalized Recommendations.
    • Added logic to show a "Rate movies to get recommendations" message if the profile is empty.

Important Note on User Behavior

The algorithm treats Ratings and Likes as separate signals.

  • If a user Likes a movie, they get recommendations based on it.
  • If a user Un-Likes a movie but keeps the Rating (e.g., 4 stars), the system still uses that movie for recommendations.
  • Why? Because a high rating indicates preference, even if the movie isn't in the "Favorites" list. To stop recommendations based on a movie, the user must essentially "forget" it (delete from DB/Watchlist).

How to Test

  1. Fresh Start: Clear app storage to remove old movies with missing genre data.
  2. Seed Data: Search for a movie (e.g., "The Matrix"), open details, and Like it. (This saves the Sci-Fi genre).
  3. Check Home: The recommendation row should now be populated with Sci-Fi movies.
  4. Check Logs: Filter Logcat for RecEngine to see the scoring math in real-time.
Edited by AGHARAHIMOV AGHASALIM

Merge request reports