"""ORM model for the global business → agent / chain mapping (业务链条管理). A "business mapping" row binds a fixed business code (3Q / 6BF / 6-1…6-4 / 7BF / 8BF / AFX) to an optional 智能体 (``agent_id``) and an optional 业务链条 (``chain_id`` → a ``roundtable_chains`` row, which must be **public** so every account can resolve it). Used to auto-pick the business chain when a task page launches the multi-agent roundtable. Unlike ``roundtable_chains`` (per-user), this mapping is **global / shared** — there is no ``user_id`` column; all accounts see and use the same configuration. The fixed business rows are seeded on startup; users only fill in the agent / chain columns from the management page. ``agent_name`` / ``chain_title`` are denormalized display snapshots so the table renders without cross-referencing and survives a later agent/chain rename or delete (the picked id still drives the auto-flow). """ from __future__ import annotations from datetime import UTC, datetime from sqlalchemy import Integer, String from sqlalchemy.orm import Mapped, mapped_column from deerflow.persistence.base import Base from deerflow.persistence.types import BeijingDateTime class BusinessMappingRow(Base): __tablename__ = "business_mapping" # Business code is the natural primary key (e.g. "3Q", "6BF"). Global, no user scope. business_code: Mapped[str] = mapped_column(String(32), primary_key=True) # Display label shown in the 业务 column (e.g. "任务FX"). label: Mapped[str] = mapped_column(String(128), nullable=False, default="") # Picked 智能体 (暂存不用,自动流程当前不消费此字段). NULL = 未配置. agent_id: Mapped[str | None] = mapped_column(String(64), nullable=True) agent_name: Mapped[str | None] = mapped_column(String(191), nullable=True) # Picked 业务链条 → roundtable_chains.id (须为 public). NULL = 未配置. chain_id: Mapped[str | None] = mapped_column(String(64), nullable=True) chain_title: Mapped[str | None] = mapped_column(String(512), nullable=True) # Fixed display order for the management table. sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0) created_at: Mapped[datetime] = mapped_column( BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC) ) updated_at: Mapped[datetime] = mapped_column( BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC), )