06/18 Phase 7

This commit is contained in:
2026-06-18 09:29:33 -04:00
parent d1383a9835
commit d54e5e2127
16 changed files with 563 additions and 8 deletions
+48
View File
@@ -0,0 +1,48 @@
"""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 15")
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,
}