fix: delete agent 500 error + dynamic personality + deployment guide

- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions,
  schedules, executions, team_members) and unbind goals/tasks before delete
- Remove hardcoded personality templates in Android, replace with dynamic
  system prompt generation from name + description
- Set promptSectionsEnabled=false to bypass PromptComposer for personality
- Add Tencent Cloud Linux deployment guide (Docker Compose)
- Accumulated backend service updates, frontend UI fixes, Android app changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 01:17:21 +08:00
parent 86b98865e3
commit beff3fac8d
1084 changed files with 117315 additions and 1281 deletions

View File

@@ -0,0 +1,61 @@
"""
工作区 (Workspace) 模型 — 多租户数据隔离
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, Index, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class Workspace(Base):
"""工作区/租户表"""
__tablename__ = "workspaces"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="工作区ID")
name = Column(String(100), nullable=False, comment="工作区名称")
description = Column(Text, comment="描述")
avatar = Column(String(500), nullable=True, comment="Logo URL")
is_default = Column(Integer, default=0, comment="是否为默认工作区: 0=否 1=是")
owner_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="所有者ID")
max_members = Column(Integer, default=50, comment="最大成员数")
settings = Column(JSON, nullable=True, comment="工作区设置")
status = Column(String(20), default="active", comment="状态: active/disabled/deleted")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
owner = relationship("User", backref="owned_workspaces")
memberships = relationship("WorkspaceMembership", back_populates="workspace", cascade="all, delete-orphan")
def to_dict(self):
return {
"id": self.id,
"name": self.name,
"description": self.description,
"avatar": self.avatar,
"is_default": bool(self.is_default),
"owner_id": self.owner_id,
"max_members": self.max_members,
"settings": self.settings,
"status": self.status,
"created_at": self.created_at.isoformat() if self.created_at else None,
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
}
class WorkspaceMembership(Base):
"""工作区成员关联表"""
__tablename__ = "workspace_memberships"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="关联ID")
workspace_id = Column(CHAR(36), ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False, comment="工作区ID")
user_id = Column(CHAR(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, comment="用户ID")
role = Column(String(20), nullable=False, default="member", comment="角色: admin/member")
joined_at = Column(DateTime, default=func.now(), comment="加入时间")
workspace = relationship("Workspace", back_populates="memberships")
user = relationship("User", backref="workspace_memberships")
__table_args__ = (
Index("ix_ws_membership_workspace_user", "workspace_id", "user_id", unique=True),
)