Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7813731ea9 | |||
| 0dd31f5a4f | |||
| 7a583c0486 | |||
| a4c30b0557 |
@@ -13,4 +13,9 @@ preset:
|
|||||||
- "app/models/base.py"
|
- "app/models/base.py"
|
||||||
- "app/models/user.py"
|
- "app/models/user.py"
|
||||||
- "app/utils/s3.py"
|
- "app/utils/s3.py"
|
||||||
|
- "app/auth.py"
|
||||||
|
|
||||||
|
db_model:
|
||||||
|
- "app/models/*"
|
||||||
|
- "app/db.py"
|
||||||
- "app/auth.py"
|
- "app/auth.py"
|
||||||
+3
-1
@@ -16,4 +16,6 @@ wheels/
|
|||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
.git
|
.git
|
||||||
|
|
||||||
|
prompts/
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
from sqlalchemy import Column, DateTime, String, ForeignKey, UniqueConstraint
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
class Follow(Base, AutoID):
|
||||||
|
"""用户关注关系表"""
|
||||||
|
__tablename__ = "follows"
|
||||||
|
|
||||||
|
follower_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True)
|
||||||
|
followee_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True)
|
||||||
|
|
||||||
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
|
||||||
|
# 联合唯一索引:防止重复关注
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint("follower_id", "followee_id", name="uq_follower_followee"),
|
||||||
|
)
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
class LibraryItem(Base, AutoID):
|
||||||
|
"""工作区共享媒体/文件资源库"""
|
||||||
|
__tablename__ = "library_items"
|
||||||
|
|
||||||
|
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
||||||
|
# 自引用外键,支持无限级文件夹嵌套
|
||||||
|
parent_id = Column(String(32), ForeignKey("library_items.id", ondelete="CASCADE"), nullable=True, index=True)
|
||||||
|
|
||||||
|
name = Column(String, nullable=False)
|
||||||
|
# 节点类型:'folder' (文件夹) 或 'file' (真实文件)
|
||||||
|
item_type = Column(String, default="file", nullable=False)
|
||||||
|
|
||||||
|
# --- 以下为真实文件(item_type='file')的核心字段 ---
|
||||||
|
s3_key = Column(String, nullable=True) # S3 中的 Object Key
|
||||||
|
file_size = Column(BigInteger, nullable=True) # 文件大小(字节数 Bytes),用于统计容量占用
|
||||||
|
mime_type = Column(String, nullable=True) # 媒体类型,例如 'image/jpeg', 'video/mp4', 'application/pdf'
|
||||||
|
|
||||||
|
uploaded_by = Column(String(32), ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
|
||||||
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
from sqlalchemy import Column, DateTime, String, ForeignKey
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
class ProjectNode(Base, AutoID):
|
||||||
|
"""项目与文件夹的树状虚拟文件系统"""
|
||||||
|
__tablename__ = "project_nodes"
|
||||||
|
|
||||||
|
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
||||||
|
# 自引用外键:如果是根目录下的顶级节点,则 parent_id 为 Null
|
||||||
|
parent_id = Column(String(32), ForeignKey("project_nodes.id", ondelete="CASCADE"), nullable=True, index=True)
|
||||||
|
|
||||||
|
name = Column(String, nullable=False)
|
||||||
|
# 节点类型:'folder' (文件夹) 或 'project' (代表具体文件的项目实体)
|
||||||
|
node_type = Column(String, default="project", nullable=False)
|
||||||
|
|
||||||
|
# 如果是 project 节点,可以用这一列来存储其内容或配置快照(如 JSON 文本)
|
||||||
|
content = Column(String, nullable=True)
|
||||||
|
|
||||||
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
@@ -9,6 +9,8 @@ class User(Base, AutoID):
|
|||||||
google_id = Column(String, unique=True, index=True)
|
google_id = Column(String, unique=True, index=True)
|
||||||
email = Column(String, unique=True, index=True)
|
email = Column(String, unique=True, index=True)
|
||||||
name = Column(String)
|
name = Column(String)
|
||||||
|
# 类似 Twitter 的 @code 唯一标识
|
||||||
|
handle = Column(String, unique=True, index=True, nullable=True)
|
||||||
avatar = Column(String)
|
avatar = Column(String)
|
||||||
|
|
||||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger, UniqueConstraint
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
class Workspace(Base, AutoID):
|
||||||
|
"""工作区表"""
|
||||||
|
__tablename__ = "workspaces"
|
||||||
|
|
||||||
|
name = Column(String, nullable=False)
|
||||||
|
# 存储容量上限(单位:字节 Bytes),默认 5GB
|
||||||
|
storage_limit = Column(BigInteger, default=5 * 1024 * 1024 * 1024)
|
||||||
|
|
||||||
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
|
||||||
|
|
||||||
|
class WorkspaceMember(Base, AutoID):
|
||||||
|
"""工作区成员及权限表"""
|
||||||
|
__tablename__ = "workspace_members"
|
||||||
|
|
||||||
|
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
||||||
|
user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True)
|
||||||
|
|
||||||
|
# 角色权限:'owner' (所有者), 'admin' (管理员), 'user' (普通用户)
|
||||||
|
role = Column(String, default="user", nullable=False)
|
||||||
|
|
||||||
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
|
||||||
|
# 一个用户在一个工作区只能有一条记录
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint("workspace_id", "user_id", name="uq_workspace_user"),
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user