from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlmodel import Session, select, func from database import get_session from models import Review, User, Profile from schemas import ReviewCreate, ReviewRead from auth import get_current_user from services.gamification import award_xp, check_and_award_badges, update_streak, XP_REWARDS router = APIRouter(prefix="/reviews", tags=["reviews"]) @router.post("/", response_model=ReviewRead) def create_review( review: ReviewCreate, session: Session = Depends(get_session), current_user: User = Depends(get_current_user) ): # Create model from schema data + user_id db_review = Review(**review.model_dump(), user_id=current_user.id) session.add(db_review) session.flush() # Ensure ID is generated for badge checks if needed # Check if this is user's first review for bonus XP # We check relative to THIS review just being added (id > 0) review_count = session.exec( select(func.count(Review.id)).where(Review.user_id == current_user.id) ).one() or 0 # Award XP xp_amount = XP_REWARDS["review_write"] if review_count <= 1: # This is the first one xp_amount += XP_REWARDS["first_review"] # Bonus for first review try: award_xp(session, current_user, xp_amount, "review") update_streak(session, current_user) check_and_award_badges(session, current_user) except Exception as e: # Don't fail the review if gamification fails, but log it print(f"Error in gamification service during review: {e}") session.commit() session.refresh(db_review) return db_review @router.get("/") def read_reviews( show_id: Optional[int] = None, venue_id: Optional[int] = None, song_id: Optional[int] = None, performance_id: Optional[int] = None, tour_id: Optional[int] = None, year: Optional[int] = None, offset: int = 0, limit: int = Query(default=100, le=100), session: Session = Depends(get_session) ): query = select(Review) if show_id: query = query.where(Review.show_id == show_id) if venue_id: query = query.where(Review.venue_id == venue_id) if song_id: query = query.where(Review.song_id == song_id) if performance_id: query = query.where(Review.performance_id == performance_id) if tour_id: query = query.where(Review.tour_id == tour_id) if year: query = query.where(Review.year == year) reviews = session.exec(query.offset(offset).limit(limit)).all() # Enrich with user profile data result = [] for review in reviews: user = session.get(User, review.user_id) profile = session.exec( select(Profile).where(Profile.user_id == review.user_id) ).first() result.append({ **review.model_dump(), "user": { "id": user.id if user else review.user_id, "username": profile.username if profile else f"User {review.user_id}", "display_name": profile.display_name if profile else None, "avatar_bg_color": user.avatar_bg_color if user else "#0F4C81", "avatar_text": user.avatar_text if user else None, } if user else None }) return result