Files
character-roleplay-backend/app/models/workspace.py
T

58 lines
2.1 KiB
Python

from typing import TYPE_CHECKING
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger, UniqueConstraint
from sqlalchemy.sql import func
from .base import AutoID, Base
if TYPE_CHECKING:
from .user import User
class Workspace(Base, AutoID):
"""工作区表"""
__tablename__ = "workspaces"
# --- 基础与个性化 ---
name = Column(String, nullable=False)
slug = Column(String, unique=True, index=True, nullable=False)
logo = Column(String, nullable=True)
description = Column(String, nullable=True)
# 存储容量上限(单位:字节 Bytes),默认 5GB
storage_limit = Column(BigInteger, default=5 * 1024 * 1024 * 1024)
storage_used = Column(BigInteger, default=0, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
class WorkspaceMember(Base, AutoID):
"""工作区成员及权限表"""
__tablename__ = "workspace_members"
workspace_id = Column(
String(Workspace.id_length()),
ForeignKey("workspaces.id", ondelete="CASCADE"),
index=True,
)
# 允许 user_id 为空,因为被邀请的人可能还没注册系统,我们先记录他的邮箱
user_id = Column(
String(User.id_length()),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=True,
index=True,
)
invite_email = Column(String, nullable=True) # 收到邀请的邮箱
# 状态:'pending' (等待加入), 'active' (已加入), 'disabled' (已禁用)
status = Column(String, default="pending", nullable=False)
# 角色权限:'owner' (所有者), 'admin' (管理员), 'user' (普通用户)
role = Column(String, default="user", nullable=False)
invite_token = Column(String, nullable=True, unique=True)
token_expires_at = Column(DateTime(timezone=True), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
# 一个用户在一个工作区只能有一条记录
__table_args__ = (
UniqueConstraint("workspace_id", "user_id", name="uq_workspace_user"),
)