""" Forum MVP models - Categories, Threads, Posts, Reactions, Reports. Job ID: MTAD-IMPL-2025-11-18-CL """ from sqlalchemy import Column, String, Text, Boolean, DateTime, Integer, ForeignKey from sqlalchemy.orm import relationship from sqlalchemy.sql import func from app.database import Base class ForumCategory(Base): """Forum Category - Discussion categories.""" __tablename__ = "forum_categories" id = Column(String(36), primary_key=True, index=True) name = Column(String(255), unique=True, nullable=False, index=True) description = Column(Text, nullable=True) order = Column(Integer, default=0, index=True) created_at = Column(DateTime, server_default=func.now()) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) # Relationships threads = relationship("ForumThread", back_populates="category", cascade="all, delete-orphan") class ForumThread(Base): """Forum Thread - Discussion thread.""" __tablename__ = "forum_threads" id = Column(String(36), primary_key=True, index=True) category_id = Column(String(36), ForeignKey("forum_categories.id"), index=True, nullable=False) author_id = Column(String(36), ForeignKey("users.id"), index=True, nullable=False) title = Column(String(500), nullable=False, index=True) pinned = Column(Boolean, default=False, index=True) locked = Column(Boolean, default=False, index=True) created_at = Column(DateTime, server_default=func.now(), index=True) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), index=True) # Relationships category = relationship("ForumCategory", back_populates="threads") author = relationship("User", back_populates="forum_threads") posts = relationship("ForumPost", back_populates="thread", cascade="all, delete-orphan") class ForumPost(Base): """Forum Post - Individual post/reply in a thread.""" __tablename__ = "forum_posts" id = Column(String(36), primary_key=True, index=True) thread_id = Column(String(36), ForeignKey("forum_threads.id"), index=True, nullable=False) author_id = Column(String(36), ForeignKey("users.id"), index=True, nullable=False) parent_post_id = Column(String(36), ForeignKey("forum_posts.id"), index=True, nullable=True) content = Column(Text, nullable=False) # May contain PHI deleted_at = Column(DateTime, nullable=True) created_at = Column(DateTime, server_default=func.now(), index=True) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), index=True) # Relationships thread = relationship("ForumThread", back_populates="posts") author = relationship("User", back_populates="forum_posts") reactions = relationship("ForumReaction", back_populates="post", cascade="all, delete-orphan") reports = relationship("ForumReport", back_populates="post", cascade="all, delete-orphan") class ForumReaction(Base): """Forum Reaction - Emoji reactions to posts.""" __tablename__ = "forum_reactions" id = Column(String(36), primary_key=True, index=True) post_id = Column(String(36), ForeignKey("forum_posts.id"), index=True, nullable=False) user_id = Column(String(36), ForeignKey("users.id"), index=True, nullable=False) emoji_code = Column(String(20), nullable=False) # e.g., "👍", "❤️", "😢" created_at = Column(DateTime, server_default=func.now(), index=True) # Relationships post = relationship("ForumPost", back_populates="reactions") user = relationship("User", back_populates="forum_reactions") class ForumReport(Base): """Forum Report - Content moderation reports.""" __tablename__ = "forum_reports" id = Column(String(36), primary_key=True, index=True) post_id = Column(String(36), ForeignKey("forum_posts.id"), index=True, nullable=False) reporter_id = Column(String(36), ForeignKey("users.id"), index=True, nullable=False) reason = Column(String(255), nullable=False) status = Column(String(50), default="open", index=True) # open, resolved, dismissed moderator_notes = Column(Text, nullable=True) resolved_at = Column(DateTime, nullable=True) created_at = Column(DateTime, server_default=func.now(), index=True) # Relationships post = relationship("ForumPost", back_populates="reports") reporter = relationship("User", back_populates="forum_reports")