后端: - 索引/唯一键改用 mysql_length 前缀索引,适配 MySQL 767 字节限制(error 1071):knowledge_notes、knowledge_entities、knowledge_graph_blacklist、agent_skills、feedback - engine.py 新增 _ensure_orm_columns_sync:启动时对比 ORM 元数据,自动 ALTER TABLE 补齐缺失的可空/带默认值列及其索引 - 新增 scripts/audit_index_key_lengths.py 审计全部索引键长度 - 更新 backend/CLAUDE.md 迁移说明 前端: - 智能体卡片/技能列表:所有者与管理员可见未发布徽标 - 智能体广场:服务端查询进行中时灰显旧结果并悬浮加载提示 - 排行榜入口从 Header 移到欢迎语旁 - threads/hooks.ts:抽取 updateCachedThreadLists 统一处理数组与分页两种缓存形态 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
39 lines
1.7 KiB
Python
39 lines
1.7 KiB
Python
"""ORM model for user feedback on runs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import Index, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime
|
|
|
|
|
|
class FeedbackRow(Base):
|
|
__tablename__ = "feedback"
|
|
|
|
# Prefix-unique instead of UniqueConstraint: a plain unique over three
|
|
# String(64) columns is (64+64+64)*4 = 768 bytes — one byte over MySQL's
|
|
# legacy 767-byte index limit (utf8mb4). Capping user_id's key part at 63
|
|
# chars (ids are 36-char UUIDs in practice) brings it to 764 bytes.
|
|
# mysql_length is ignored on SQLite/Postgres.
|
|
__table_args__ = (Index("uq_feedback_thread_run_user", "thread_id", "run_id", "user_id", unique=True, mysql_length={"user_id": 63}),)
|
|
|
|
feedback_id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
run_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
|
thread_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
|
user_id: Mapped[str | None] = mapped_column(String(64), index=True)
|
|
message_id: Mapped[str | None] = mapped_column(String(64))
|
|
# message_id is an optional RunEventStore event identifier —
|
|
# allows feedback to target a specific message or the entire run
|
|
|
|
rating: Mapped[int] = mapped_column(nullable=False)
|
|
# +1 (thumbs-up) or -1 (thumbs-down)
|
|
|
|
comment: Mapped[str | None] = mapped_column(Text)
|
|
# Optional text feedback from the user
|
|
|
|
created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=lambda: datetime.now(UTC))
|