""" app/models/fission.py — fission_tasks Alembic 010 第11环裂变引擎(1爆款→N套完整笔记包) reference_level: low/mid/high(参考程度) status: pending/generating/done/failed """ from datetime import datetime from sqlalchemy import ( BigInteger, DateTime, ForeignKey, Index, Integer, String, Text, func, ) from sqlalchemy.orm import Mapped, mapped_column from app.core.database import Base class FissionTask(Base): """裂变任务:1爆款→N套完整笔记包(第11环),在工作台内呈现。""" __tablename__ = "fission_tasks" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) workspace_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False ) # 爆款源笔记内容(文案+图描述),JSON存储 source_note: Mapped[str | None] = mapped_column( Text, comment="爆款源笔记内容(文案+图描述,JSON存储)" ) # 参考程度:low/mid/high reference_level: Mapped[str] = mapped_column( String(10), default="mid", nullable=False, comment="参考程度: low/mid/high" ) # 裂变套数(默认3套) fanout_count: Mapped[int] = mapped_column( Integer, default=3, nullable=False, comment="裂变套数(默认3套)" ) # 状态机 status: Mapped[str] = mapped_column( String(20), default="pending", nullable=False, comment="状态: pending/generating/done/failed" ) created_at: Mapped[datetime] = mapped_column( DateTime, server_default=func.now(), nullable=False ) __table_args__ = ( Index("idx_fission_tasks_workspace_id", "workspace_id"), ) class FissionNote(Base): """裂变产出的单套完整笔记包(一次LLM出N套,每套落一行)。 对齐上线版 split.js handleContentSplit:每套含 标题/正文/标签/封面/imagePlan, 带评分+裂变维度+生图结果。北哥在独立展示页查看。 """ __tablename__ = "fission_notes" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) fission_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("fission_tasks.id", ondelete="CASCADE"), nullable=False ) workspace_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False ) seq: Mapped[int] = mapped_column( Integer, default=0, nullable=False, comment="第几套(0起)" ) # 完整笔记包 JSON:title/content/tags/coverTitle/imagePlan/dimension/audience/scene/painPoint/keywords note_json: Mapped[str | None] = mapped_column( Text, comment="完整笔记包JSON" ) # 生图结果 JSON:[{role,name,image_url,error}...] images_json: Mapped[str | None] = mapped_column( Text, comment="生图结果JSON" ) score: Mapped[int] = mapped_column(Integer, default=0, nullable=False) passed: Mapped[bool] = mapped_column( Integer, default=0, nullable=False, comment="是否过线(>=80)" ) needs_optimization: Mapped[bool] = mapped_column( Integer, default=0, nullable=False, comment="不达标降级草稿标记" ) dimension: Mapped[str | None] = mapped_column( String(64), comment="裂变维度: 换角度/换痛点/换人群" ) status: Mapped[str] = mapped_column( String(20), default="pending", nullable=False, comment="状态: pending/scored/image_done/failed" ) created_at: Mapped[datetime] = mapped_column( DateTime, server_default=func.now(), nullable=False ) __table_args__ = ( Index("idx_fission_notes_fission_id", "fission_id"), Index("idx_fission_notes_workspace_id", "workspace_id"), )