"""Review business logic.""" from sqlalchemy.exc import IntegrityError from app.extensions import db from app.models.review import Review class ReviewError(ValueError): pass def create_review(listing, author, rating: int, body: str | None = None): """Leave a review for a seller. Listing must be sold. Returns Review.""" from app.models.enums import ListingStatus if listing.status != ListingStatus.sold: raise ReviewError("can only review sold listings") if listing.user_id == author.id: raise ReviewError("cannot review your own listing") if rating not in range(1, 6): raise ReviewError("rating must be 1–5") review = Review( listing_id=listing.id, author_id=author.id, seller_id=listing.user_id, rating=rating, body=(body or "").strip() or None, ) db.session.add(review) try: db.session.commit() except IntegrityError: db.session.rollback() raise ReviewError("you have already reviewed this listing") return review def seller_rating(user_id) -> dict: """Return avg rating and count for a seller.""" from app.extensions import db result = (db.session.query( db.func.round(db.func.avg(Review.rating), 1).label("avg"), db.func.count(Review.id).label("count")) .filter(Review.seller_id == user_id) .first()) return { "avg": float(result.avg) if result.avg else None, "count": result.count or 0, }