quality-inspection-platform/app/models.py
qihongkun 3ca520e398 feat: 新增环境配置管理和接口编辑增强
- 新增环境配置(EnvironmentConfig)的增删改查和激活功能
- API 接口支持 description、request_params、response_params 字段
- 接口管理页面支持抽屉内编辑(替代跳转编辑页)
- 新增版本管理页面和工作流列表页面
- catalog_snapshot 返回 environments 数据

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 15:44:21 +08:00

235 lines
9.8 KiB
Python

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Text, func
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String(64), nullable=False, unique=True, index=True)
password_hash = Column(String(128), nullable=False)
display_name = Column(String(64), nullable=False, default="")
role = Column(String(32), nullable=False, default="user", index=True) # superadmin | user
is_active = Column(Boolean, nullable=False, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class UserApiKey(Base):
__tablename__ = "user_api_keys"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, nullable=False, index=True)
key_prefix = Column(String(16), nullable=False, index=True)
key_hash = Column(String(128), nullable=False, unique=True, index=True)
key_hint = Column(String(8), nullable=False, default="")
expires_at = Column(DateTime(timezone=True), nullable=True)
is_active = Column(Boolean, nullable=False, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class ApiDefinition(Base):
__tablename__ = "api_definitions"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, index=True)
folder_path = Column(String(255), nullable=False, default="", index=True)
method = Column(String(16), nullable=False)
url = Column(String(512), nullable=False)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
config_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class Workflow(Base):
__tablename__ = "workflows"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, index=True)
folder_path = Column(String(255), nullable=False, default="", index=True)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
definition_json = Column(Text, nullable=False, default='{"nodes":[],"edges":[],"variables":{}}')
default_headers_json = Column(Text, nullable=False, default="{}")
last_run_json = Column(Text, nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class MockDataset(Base):
__tablename__ = "mock_datasets"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, unique=True, index=True)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
data_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class McpToolConfig(Base):
__tablename__ = "mcp_tool_configs"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, unique=True, index=True)
enabled = Column(Boolean, nullable=False, default=True)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
config_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class SshProfile(Base):
__tablename__ = "ssh_profiles"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, index=True)
host = Column(String(255), nullable=False)
port = Column(Integer, nullable=False, default=22)
username = Column(String(128), nullable=False)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
config_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class SshScript(Base):
__tablename__ = "ssh_scripts"
id = Column(Integer, primary_key=True, index=True)
profile_id = Column(Integer, nullable=False, index=True)
name = Column(String(128), nullable=False, index=True)
description = Column(String(255), nullable=False, default="")
source_type = Column(String(16), nullable=False, default="inline") # inline | file
content = Column(Text, nullable=False, default="")
storage_path = Column(String(512), nullable=False, default="")
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class SshShortcut(Base):
__tablename__ = "ssh_shortcuts"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, index=True)
command = Column(Text, nullable=False)
description = Column(String(255), nullable=False, default="")
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
class FolderEntry(Base):
__tablename__ = "folder_entries"
id = Column(Integer, primary_key=True, index=True)
target = Column(String(32), nullable=False, index=True) # apis | workflows
path = Column(String(255), nullable=False, index=True)
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
class WorkflowBatch(Base):
__tablename__ = "workflow_batches"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, default="")
status = Column(String(16), nullable=False, default="draft") # draft | running | success | failed | partial
triggered_by = Column(String(32), nullable=False, default="ui")
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
base_url = Column(String(512), nullable=False, default="")
fail_fast = Column(Boolean, nullable=False, default=True)
workflow_ids_json = Column(Text, nullable=False, default="[]")
summary_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
finished_at = Column(DateTime(timezone=True), nullable=True)
class WorkflowRun(Base):
__tablename__ = "workflow_runs"
id = Column(Integer, primary_key=True, index=True)
batch_id = Column(Integer, nullable=True, index=True)
workflow_id = Column(Integer, nullable=False, index=True)
workflow_name = Column(String(128), nullable=False, default="")
run_type = Column(String(16), nullable=False, default="full") # full | node
node_id = Column(String(64), nullable=True)
triggered_by = Column(String(32), nullable=False, default="ui") # ui | mcp | api
status = Column(String(16), nullable=False, default="success") # success | failed
duration_ms = Column(Integer, nullable=False, default=0)
summary_json = Column(Text, nullable=False, default="{}")
payload_json = Column(Text, nullable=False, default="{}")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
class EnvironmentConfig(Base):
__tablename__ = "environment_configs"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(128), nullable=False, index=True)
base_url = Column(String(512), nullable=False, default="")
auth_token = Column(String(512), nullable=False, default="")
description = Column(Text, nullable=False, default="")
status = Column(String(16), nullable=False, default="draft") # active | draft | archived
creator_id = Column(Integer, nullable=False, default=1, index=True)
creator_name = Column(String(64), nullable=False, default="admin")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)