后端: - InstanceGroup 模型 (name/db_type/permissions JSON/is_active) - user_groups 关联表 (用户-权限组 M2M + 权限覆盖) - Instance 模型增加 group_id FK - User 模型增加 groups 关系 - API: CRUD + 实例关联 + 用户分配 + 权限组过滤 - 15 个新测试 (CRUD/关联/权限检查/参数校验) — 217/217 passing 前端: - InstanceGroupPage: 左右布局(列表+详情) - 权限配置: 5类17项权限勾选 (查询/DDL/工单/数据操作/管理) - 实例关联/用户关联弹框 - 侧边栏增加权限组菜单 (数据源分组下) - 路由 + 权限注册
37 lines
1.6 KiB
Python
37 lines
1.6 KiB
Python
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, func
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from app.core.database import Base
|
|
|
|
|
|
class Instance(Base):
|
|
__tablename__ = "instances"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
name = Column(String(100), nullable=False)
|
|
db_type = Column(String(20), nullable=False) # mysql / postgres / redis / mongo
|
|
host = Column(String(200), nullable=False)
|
|
port = Column(Integer, nullable=False)
|
|
username = Column(String(100), nullable=False)
|
|
password = Column(String(500), nullable=False) # encrypted
|
|
database = Column(String(100), nullable=True)
|
|
env = Column(String(20), default="development") # production / staging / development
|
|
description = Column(Text, nullable=True)
|
|
status = Column(String(20), default="disconnected") # connected / disconnected / error
|
|
version = Column(String(50), nullable=True)
|
|
|
|
# 新增字段
|
|
access_mode = Column(String(20), default="readwrite") # readwrite / read / write
|
|
workflow = Column(Text, nullable=True) # JSON: [{stage, role, assignee}]
|
|
excluded_databases = Column(Text, nullable=True) # JSON: ["sys", "information_schema", ...]
|
|
mask_fields = Column(Text, nullable=True) # JSON: [{table, field, rule}]
|
|
|
|
# 权限组关联
|
|
group_id = Column(Integer, ForeignKey("instance_groups.id", ondelete="SET NULL"), nullable=True)
|
|
|
|
created_at = Column(DateTime, server_default=func.now())
|
|
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
|
|
|
|
# 关系
|
|
group = relationship("InstanceGroup", back_populates="instances")
|