企業內部新聞彙整與分析系統 - 自動新聞抓取 (Digitimes, 經濟日報, 工商時報) - AI 智慧摘要 (OpenAI/Claude/Ollama) - 群組管理與訂閱通知 - 已清理 Python 快取檔案 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
91 lines
3.8 KiB
Python
91 lines
3.8 KiB
Python
"""
|
|
讀者互動資料模型(訂閱、收藏、留言、筆記)
|
|
"""
|
|
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")
|