PMFlow/backend/app/models/feishu_item.py

79 lines
3.8 KiB
Python

"""飞书分流队列项模型"""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import (
BigInteger,
Boolean,
Float,
ForeignKey,
Index,
Integer,
TEXT,
TIMESTAMP,
VARCHAR,
text,
)
from sqlalchemy.orm import Mapped, mapped_column
from .base import Base
from .types import JSONB
class FeishuItem(Base):
__tablename__ = "feishu_items"
__table_args__ = (
Index(
"uq_feishu_items_tenant_message_root",
"tenant_id",
"feishu_message_id",
unique=True,
postgresql_where=text("split_from_item_id IS NULL AND feishu_message_id IS NOT NULL"),
sqlite_where=text("split_from_item_id IS NULL AND feishu_message_id IS NOT NULL"),
),
Index(
"uq_feishu_items_tenant_message_split",
"tenant_id",
"feishu_message_id",
"split_from_item_id",
unique=True,
postgresql_where=text("split_from_item_id IS NOT NULL AND feishu_message_id IS NOT NULL"),
sqlite_where=text("split_from_item_id IS NOT NULL AND feishu_message_id IS NOT NULL"),
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
feishu_message_id: Mapped[Optional[str]] = mapped_column(VARCHAR(128), nullable=True, index=True)
project_score: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
signal_confidence: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
raw_message: Mapped[str] = mapped_column(TEXT, nullable=False)
split_from_item_id: Mapped[Optional[int]] = mapped_column(
BigInteger, ForeignKey("feishu_items.id"), nullable=True, index=True
)
level: Mapped[str] = mapped_column(VARCHAR(20), nullable=False, index=True)
level_confidence: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
level_reasoning: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)
card_type: Mapped[str] = mapped_column(VARCHAR(30), nullable=False, default="signal", index=True)
route_status: Mapped[str] = mapped_column(VARCHAR(30), nullable=False, default="pending", index=True)
matched_project_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True, index=True)
source_chat_id: Mapped[Optional[str]] = mapped_column(VARCHAR(128), nullable=True)
source_sender: Mapped[Optional[str]] = mapped_column(VARCHAR(120), nullable=True)
source_sender_open_id: Mapped[Optional[str]] = mapped_column(VARCHAR(128), nullable=True)
source_occurred_at: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP, nullable=True)
ai_output: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)
decision_reason: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)
blocking_reason: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)
safe_to_auto_execute: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
auto_execute_state: Mapped[Optional[str]] = mapped_column(VARCHAR(30), nullable=True, index=True)
dedupe_key: Mapped[Optional[str]] = mapped_column(VARCHAR(255), nullable=True, index=True)
message_class: Mapped[Optional[str]] = mapped_column(VARCHAR(30), nullable=True, index=True)
occurrence_count: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
next_step_text: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)
undoable_until: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP, nullable=True)
result_payload: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
queue_visible: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, index=True)
processed_at: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP, nullable=True)
dismissed_reason: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True)