""" 讀者互動資料模型(訂閱、收藏、留言、筆記) """ from datetime import datetime from sqlalchemy import String, Boolean, ForeignKey, Text, UniqueConstraint, Index from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import Optional, List, TYPE_CHECKING from app.db.session import Base if TYPE_CHECKING: from app.models.user import User from app.models.group import Group from app.models.report import Report class Subscription(Base): """訂閱表""" __tablename__ = "subscriptions" __table_args__ = ( UniqueConstraint("user_id", "group_id", name="uk_user_group"), ) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), nullable=False) group_id: Mapped[int] = mapped_column(ForeignKey("groups.id", ondelete="CASCADE"), nullable=False) email_notify: Mapped[bool] = mapped_column(Boolean, default=True, comment="是否Email通知") created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow) # 關聯 user: Mapped["User"] = relationship(back_populates="subscriptions") group: Mapped["Group"] = relationship(back_populates="subscriptions") class Favorite(Base): """收藏表""" __tablename__ = "favorites" __table_args__ = ( UniqueConstraint("user_id", "report_id", name="uk_user_report"), ) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), nullable=False) report_id: Mapped[int] = mapped_column(ForeignKey("reports.id", ondelete="CASCADE"), nullable=False) created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow) # 關聯 user: Mapped["User"] = relationship(back_populates="favorites") report: Mapped["Report"] = relationship(back_populates="favorites") class Comment(Base): """留言表""" __tablename__ = "comments" __table_args__ = ( Index("idx_comments_report", "report_id"), ) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) report_id: Mapped[int] = mapped_column(ForeignKey("reports.id", ondelete="CASCADE"), nullable=False) user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False, comment="留言內容") parent_id: Mapped[Optional[int]] = mapped_column(ForeignKey("comments.id"), comment="父留言ID") is_deleted: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(default=datetime.utcnow, onupdate=datetime.utcnow) # 關聯 report: Mapped["Report"] = relationship(back_populates="comments") user: Mapped["User"] = relationship(back_populates="comments") parent: Mapped[Optional["Comment"]] = relationship(remote_side=[id], backref="replies") class Note(Base): """個人筆記表""" __tablename__ = "notes" __table_args__ = ( Index("idx_notes_user_report", "user_id", "report_id"), ) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), nullable=False) report_id: Mapped[int] = mapped_column(ForeignKey("reports.id", ondelete="CASCADE"), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False, comment="筆記內容") created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(default=datetime.utcnow, onupdate=datetime.utcnow) # 關聯 user: Mapped["User"] = relationship(back_populates="notes") report: Mapped["Report"] = relationship(back_populates="notes")