AIdea-Server / src /api /recommendation_routes.py
β€œbotayla”
update
0b64e1c
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import Dict, Any
from src.auth.dependencies import get_current_user
from src.db.firebase import get_firebase_db
from src.recommendation.recommender import RecommendationService
from src.utils.logger import setup_logger
logger = setup_logger(__name__)
router = APIRouter(prefix="/recommendations", tags=["Recommendations"])
recommendation_service = RecommendationService()
GENERAL_VIDEOS = [
{
"videoId": "aircAruvnKk",
"title": "But what is a neural network?",
"channelTitle": "3Blue1Brown",
"thumbnail": "https://img.youtube.com/vi/aircAruvnKk/hqdefault.jpg",
},
{
"videoId": "rfscVS0vtbw",
"title": "Learn Python in 4 hours",
"channelTitle": "freeCodeCamp",
"thumbnail": "https://img.youtube.com/vi/rfscVS0vtbw/hqdefault.jpg",
},
{
"videoId": "8jLOx1hD3_o",
"title": "Harvard CS50 2023",
"channelTitle": "CS50",
"thumbnail": "https://img.youtube.com/vi/8jLOx1hD3_o/hqdefault.jpg",
},
{
"videoId": "kqtD5dpn9C8",
"title": "Python for Beginners – Full Course",
"channelTitle": "Programming with Mosh",
"thumbnail": "https://img.youtube.com/vi/kqtD5dpn9C8/hqdefault.jpg",
},
{
"videoId": "Ke90Tje7VS0",
"title": "React JS Crash Course",
"channelTitle": "Traversy Media",
"thumbnail": "https://img.youtube.com/vi/Ke90Tje7VS0/hqdefault.jpg",
},
{
"videoId": "bMknfKXIFA8",
"title": "Machine Learning Course for Beginners",
"channelTitle": "freeCodeCamp",
"thumbnail": "https://img.youtube.com/vi/bMknfKXIFA8/hqdefault.jpg",
},
{
"videoId": "ua-CiDNNj30",
"title": "Fullstack Web Dev in 2024",
"channelTitle": "Fireship",
"thumbnail": "https://img.youtube.com/vi/ua-CiDNNj30/hqdefault.jpg",
},
{
"videoId": "qiQR5rTSshw",
"title": "C++ Tutorial for Beginners",
"channelTitle": "freeCodeCamp",
"thumbnail": "https://img.youtube.com/vi/qiQR5rTSshw/hqdefault.jpg",
},
{
"videoId": "zOjov-2OZ0E",
"title": "100+ Linux Things You Should Know",
"channelTitle": "Fireship",
"thumbnail": "https://img.youtube.com/vi/zOjov-2OZ0E/hqdefault.jpg",
},
{
"videoId": "W6NZfCO5SIk",
"title": "JavaScript Tutorial for Beginners",
"channelTitle": "Programming with Mosh",
"thumbnail": "https://img.youtube.com/vi/W6NZfCO5SIk/hqdefault.jpg",
},
]
MIN_INTERACTIONS_FOR_PERSONALIZATION = 5
@router.get("")
async def get_recommendations(
current_user=Depends(get_current_user),
db=Depends(get_firebase_db),
limit: int = Query(default=5, ge=1, le=20),
) -> Dict[str, Any]:
user_id = current_user.id # βœ… your model uses "id"
if not user_id:
raise HTTPException(status_code=401, detail="Invalid user")
logger.info(f"🎯 Getting recommendations for user: {user_id}")
try:
# βœ… Use notesCount directly from user
notes_count = getattr(current_user, "notesCount", 0) or 0
is_personalized = notes_count >= MIN_INTERACTIONS_FOR_PERSONALIZATION
if is_personalized:
logger.info(f"βœ… Personalized mode for {user_id} ({notes_count} notes)")
# ⚠️ for now you can still return general videos
# until you build real recommender
recommendations = await recommendation_service.get_recommendations_for_user(
db=db,
user_id=user_id,
limit=limit,
)
else:
logger.info(f"🌱 General mode for {user_id} ({notes_count}/{MIN_INTERACTIONS_FOR_PERSONALIZATION} notes)")
recommendations = []
except Exception as e:
logger.error(f"❌ Failed to get recommendations for {user_id}: {e}")
raise HTTPException(
status_code=500,
detail="Failed to fetch recommendations.",
)
return {
"status": "success",
"is_personalized": is_personalized,
"interactions_count": notes_count, # βœ… mapped correctly
"interactions_needed": MIN_INTERACTIONS_FOR_PERSONALIZATION,
"count": len(recommendations),
"recommendations": recommendations,
}