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:
61
backend/app/models/workspace.py
Normal file
61
backend/app/models/workspace.py
Normal 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),
|
||||
)
|
||||
Reference in New Issue
Block a user