- 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>
62 lines
2.8 KiB
Python
62 lines
2.8 KiB
Python
"""
|
|
工作区 (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),
|
|
)
|