"""User ratings -- section 17, additive (accounts/ratings/watchlist). Polymorphic across movie/series, same shape as WatchProviderOffering and TrendingEntry: `entity_type` + `entity_id` rather than a separate ratings table per entity type.""" from __future__ import annotations import uuid from sqlalchemy import Float, ForeignKey, Index, String, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column from app.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin class Rating(Base, UUIDPrimaryKeyMixin, TimestampMixin): __tablename__ = "ratings" __table_args__ = ( UniqueConstraint("user_id", "entity_type", "entity_id"), Index("ix_ratings_entity", "entity_type", "entity_id"), ) user_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) entity_type: Mapped[str] = mapped_column(String(30), nullable=False) entity_id: Mapped[uuid.UUID] = mapped_column(nullable=False) # 0.5-10.0 in 0.5 steps, same scale as TMDb's own user ratings -- see # app/schemas/account.py:RatingIn for the enforced bounds. value: Mapped[float] = mapped_column(Float, nullable=False) __all__ = ["Rating"]