"""Endpoints для отзывов и рейтингов.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.core.database import get_db from app.core.security import get_current_user from app.schemas.review import ReviewCreate, ReviewResponse from app.models.project import Project from app.models.review import Review from app.models.user import User router = APIRouter(prefix="/api/reviews", tags=["reviews"]) @router.post("", response_model=ReviewResponse) async def create_review(data: ReviewCreate, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)): """Оставить отзыв на проект.""" result = await db.execute(select(Project).where(Project.id == data.project_id)) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Проект не найден") # Проверка что пользователь участвовал в проекте if user["id"] != project.client_id and user["id"] != project.proposals[0].freelancer_id if project.proposals else True: raise HTTPException(status_code=403, detail="Только участники проекта могут оставить отзыв") review = Review( project_id=data.project_id, reviewer_id=user["id"], reviewee_id=data.reviewee_id, rating=data.rating, comment=data.comment, ) db.add(review) await db.commit() await db.refresh(review) # Обновляем рейтинг пользователя result = await db.execute(select(func.avg(Review.rating)).where(Review.reviewee_id == data.reviewee_id)) avg_rating = float(result.scalar_one_or_none()) or 0.0 return ReviewResponse( id=str(review.id), project_id=review.project_id, reviewer_name="Аноним", reviewee_name="Аноним", rating=review.rating, comment=review.comment, created_at=str(review.created_at), ) @router.get("/project/{project_id}", response_model=list[ReviewResponse]) async def list_reviews(project_id: str, db: AsyncSession = Depends(get_db)): """Список отзывов по проекту.""" result = await db.execute(select(Review).where(Review.project_id == project_id)) reviews = result.scalars().all() return [ReviewResponse( id=str(r.id), project_id=r.project_id, reviewer_name="Аноним", reviewee_name="Аноним", rating=r.rating, comment=r.comment, created_at=str(r.created_at) ) for r in reviews] @router.get("/user/{user_id}", response_model=dict) async def get_user_rating(user_id: str, db: AsyncSession = Depends(get_db)): """Получить рейтинг пользователя.""" result = await db.execute(select(func.avg(Review.rating)).where(Review.reviewee_id == user_id)) avg_rating = float(result.scalar_one_or_none()) or 0.0 result2 = await db.execute(select(func.count(Review.id)).where(Review.reviewee_id == user_id)) total_reviews = int(result2.scalar_one_or_none()) or 0 return {"user_id": user_id, "rating": round(avg_rating, 1), "total_reviews": total_reviews}