第一次提交

This commit is contained in:
rjb
2026-01-19 00:09:36 +08:00
parent de4b5059e9
commit 6674060f2f
191 changed files with 40940 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
# Models package
from app.models.user import User
from app.models.workflow import Workflow
from app.models.workflow_version import WorkflowVersion
from app.models.agent import Agent
from app.models.execution import Execution
from app.models.execution_log import ExecutionLog
from app.models.model_config import ModelConfig
from app.models.data_source import DataSource
from app.models.workflow_template import WorkflowTemplate, TemplateRating, TemplateFavorite
from app.models.node_template import NodeTemplate
from app.models.permission import Role, Permission, WorkflowPermission, AgentPermission
from app.models.alert_rule import AlertRule, AlertLog
__all__ = ["User", "Workflow", "WorkflowVersion", "Agent", "Execution", "ExecutionLog", "ModelConfig", "DataSource", "WorkflowTemplate", "TemplateRating", "TemplateFavorite", "NodeTemplate", "Role", "Permission", "WorkflowPermission", "AgentPermission", "AlertRule", "AlertLog"]

View File

@@ -0,0 +1,29 @@
"""
智能体模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class Agent(Base):
"""智能体表"""
__tablename__ = "agents"
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="描述")
workflow_config = Column(JSON, nullable=False, comment="工作流配置")
version = Column(Integer, default=1, comment="版本号")
status = Column(String(20), default="draft", comment="状态: draft/published/running/stopped")
user_id = Column(CHAR(36), ForeignKey("users.id"), comment="创建者ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="agents")
def __repr__(self):
return f"<Agent(id={self.id}, name={self.name})>"

View File

@@ -0,0 +1,85 @@
"""
告警规则模型
"""
from sqlalchemy import Column, String, Text, Integer, Boolean, DateTime, ForeignKey, JSON, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class AlertRule(Base):
"""告警规则表"""
__tablename__ = "alert_rules"
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="规则描述")
# 告警类型execution_failed执行失败、execution_timeout执行超时、error_rate错误率、resource_usage资源使用
alert_type = Column(String(50), nullable=False, comment="告警类型")
# 监控目标workflow工作流、agent智能体、system系统
target_type = Column(String(50), nullable=False, comment="监控目标类型")
target_id = Column(CHAR(36), nullable=True, comment="监控目标ID为空则监控所有")
# 告警条件JSON格式
# 例如:{"threshold": 5, "time_window": 3600, "comparison": "gt"} 表示1小时内失败次数大于5
conditions = Column(JSON, nullable=False, comment="告警条件")
# 通知方式email邮件、webhookWebhook、internal站内通知
notification_type = Column(String(50), nullable=False, comment="通知方式")
notification_config = Column(JSON, nullable=True, comment="通知配置如邮箱地址、Webhook URL等")
# 状态
enabled = Column(Boolean, default=True, comment="是否启用")
# 统计信息
trigger_count = Column(Integer, default=0, comment="触发次数")
last_triggered_at = Column(DateTime, comment="最后触发时间")
# 用户关联
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="创建者ID")
# 时间戳
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="alert_rules")
def __repr__(self):
return f"<AlertRule(id={self.id}, name={self.name}, alert_type={self.alert_type})>"
class AlertLog(Base):
"""告警日志表"""
__tablename__ = "alert_logs"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="告警日志ID")
rule_id = Column(CHAR(36), ForeignKey("alert_rules.id"), nullable=False, comment="告警规则ID")
# 告警信息
alert_type = Column(String(50), nullable=False, comment="告警类型")
severity = Column(String(20), default="warning", comment="严重程度info/warning/error/critical")
message = Column(Text, nullable=False, comment="告警消息")
details = Column(JSON, comment="详细信息")
# 状态
status = Column(String(20), default="pending", comment="状态pending/sent/failed/acknowledged")
# 通知信息
notification_type = Column(String(50), comment="通知方式")
notification_result = Column(Text, comment="通知结果")
# 时间戳
triggered_at = Column(DateTime, default=func.now(), comment="触发时间")
acknowledged_at = Column(DateTime, comment="确认时间")
acknowledged_by = Column(CHAR(36), ForeignKey("users.id"), nullable=True, comment="确认人ID")
# 关系
rule = relationship("AlertRule", backref="logs")
acknowledged_user = relationship("User", foreign_keys=[acknowledged_by])
def __repr__(self):
return f"<AlertLog(id={self.id}, rule_id={self.rule_id}, severity={self.severity})>"

View File

@@ -0,0 +1,30 @@
"""
数据源模型
"""
from sqlalchemy import Column, String, Text, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class DataSource(Base):
"""数据源表"""
__tablename__ = "data_sources"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="数据源ID")
name = Column(String(100), nullable=False, comment="数据源名称")
type = Column(String(50), nullable=False, comment="数据源类型: mysql/postgresql/mongodb/redis/csv/json/api/s3")
description = Column(Text, comment="描述")
config = Column(JSON, nullable=False, comment="连接配置(加密存储敏感信息)")
status = Column(String(20), default="active", comment="状态: active/inactive/error")
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="创建者ID")
last_connected_at = Column(DateTime, comment="最后连接时间")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="data_sources")
def __repr__(self):
return f"<DataSource(id={self.id}, name={self.name}, type={self.type})>"

View File

@@ -0,0 +1,31 @@
"""
执行记录模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class Execution(Base):
"""执行记录表"""
__tablename__ = "executions"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="执行ID")
agent_id = Column(CHAR(36), ForeignKey("agents.id"), nullable=True, comment="智能体ID")
workflow_id = Column(CHAR(36), ForeignKey("workflows.id"), nullable=True, comment="工作流ID")
input_data = Column(JSON, comment="输入数据")
output_data = Column(JSON, comment="输出数据")
status = Column(String(20), nullable=False, comment="状态: pending/running/completed/failed")
error_message = Column(Text, comment="错误信息")
execution_time = Column(Integer, comment="执行时间(ms)")
task_id = Column(String(100), comment="Celery任务ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
# 关系
agent = relationship("Agent", backref="executions")
workflow = relationship("Workflow", backref="executions")
def __repr__(self):
return f"<Execution(id={self.id}, status={self.status})>"

View File

@@ -0,0 +1,29 @@
"""
执行日志模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class ExecutionLog(Base):
"""执行日志表"""
__tablename__ = "execution_logs"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="日志ID")
execution_id = Column(CHAR(36), ForeignKey("executions.id"), nullable=False, comment="执行ID")
node_id = Column(String(100), nullable=True, comment="节点ID")
node_type = Column(String(50), nullable=True, comment="节点类型")
level = Column(String(20), nullable=False, comment="日志级别: INFO/WARN/ERROR/DEBUG")
message = Column(Text, nullable=False, comment="日志消息")
data = Column(JSON, comment="附加数据")
timestamp = Column(DateTime, default=func.now(), comment="时间戳")
duration = Column(Integer, comment="执行耗时(ms)")
# 关系
execution = relationship("Execution", backref="logs")
def __repr__(self):
return f"<ExecutionLog(id={self.id}, execution_id={self.execution_id}, level={self.level})>"

View File

@@ -0,0 +1,29 @@
"""
模型配置模型
"""
from sqlalchemy import Column, String, DateTime, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class ModelConfig(Base):
"""模型配置表"""
__tablename__ = "model_configs"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="配置ID")
name = Column(String(100), nullable=False, comment="配置名称")
provider = Column(String(50), nullable=False, comment="提供商: openai/claude/local")
model_name = Column(String(100), nullable=False, comment="模型名称")
api_key = Column(String(500), nullable=False, comment="API密钥加密存储")
base_url = Column(String(255), comment="API地址")
user_id = Column(CHAR(36), ForeignKey("users.id"), comment="所属用户ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="model_configs")
def __repr__(self):
return f"<ModelConfig(id={self.id}, name={self.name}, provider={self.provider})>"

View File

@@ -0,0 +1,66 @@
"""
节点模板模型
用于管理和复用LLM节点的提示词模板
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, Boolean, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class NodeTemplate(Base):
"""节点模板表"""
__tablename__ = "node_templates"
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="模板描述")
category = Column(String(50), comment="分类: text_generation/data_analysis/code_generation/translation/summarization/qa/other")
tags = Column(JSON, comment="标签列表")
# 模板内容
prompt = Column(Text, nullable=False, comment="提示词模板(支持变量占位符,如 {{variable}}")
variables = Column(JSON, comment="变量定义列表,格式: [{\"name\": \"var1\", \"type\": \"text\", \"required\": true, \"description\": \"变量描述\"}]")
# 默认配置
provider = Column(String(50), default="deepseek", comment="默认LLM提供商")
model = Column(String(100), default="deepseek-chat", comment="默认模型")
temperature = Column(String(10), default="0.7", comment="默认温度参数")
max_tokens = Column(Integer, default=1500, comment="默认最大token数")
# 元数据
is_public = Column(Boolean, default=False, comment="是否公开")
is_featured = Column(Boolean, default=False, comment="是否精选")
use_count = Column(Integer, default=0, comment="使用次数")
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="创建者ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="node_templates")
def __repr__(self):
return f"<NodeTemplate(id={self.id}, name={self.name})>"
def to_dict(self):
"""转换为字典"""
return {
"id": self.id,
"name": self.name,
"description": self.description,
"category": self.category,
"tags": self.tags or [],
"prompt": self.prompt,
"variables": self.variables or [],
"provider": self.provider,
"model": self.model,
"temperature": self.temperature,
"max_tokens": self.max_tokens,
"is_public": self.is_public,
"is_featured": self.is_featured,
"use_count": self.use_count,
"user_id": self.user_id,
"created_at": self.created_at.isoformat() if self.created_at else None,
"updated_at": self.updated_at.isoformat() if self.updated_at else None
}

View File

@@ -0,0 +1,110 @@
"""
权限管理模型
支持RBAC基于角色的访问控制
"""
from sqlalchemy import Column, String, DateTime, JSON, ForeignKey, Boolean, Integer, Table, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
# 用户角色关联表(多对多)
user_roles = Table(
'user_roles',
Base.metadata,
Column('user_id', CHAR(36), ForeignKey('users.id', ondelete='CASCADE'), primary_key=True),
Column('role_id', CHAR(36), ForeignKey('roles.id', ondelete='CASCADE'), primary_key=True)
)
# 角色权限关联表(多对多)
role_permissions = Table(
'role_permissions',
Base.metadata,
Column('role_id', CHAR(36), ForeignKey('roles.id', ondelete='CASCADE'), primary_key=True),
Column('permission_id', CHAR(36), ForeignKey('permissions.id', ondelete='CASCADE'), primary_key=True)
)
class Role(Base):
"""角色表"""
__tablename__ = "roles"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="角色ID")
name = Column(String(50), unique=True, nullable=False, comment="角色名称")
description = Column(String(255), comment="角色描述")
is_system = Column(Boolean, default=False, comment="是否系统角色(不可删除)")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
users = relationship("User", secondary=user_roles, back_populates="roles")
permissions = relationship("Permission", secondary=role_permissions, back_populates="roles")
def __repr__(self):
return f"<Role(id={self.id}, name={self.name})>"
class Permission(Base):
"""权限表"""
__tablename__ = "permissions"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="权限ID")
name = Column(String(100), unique=True, nullable=False, comment="权限名称")
code = Column(String(100), unique=True, nullable=False, comment="权限代码workflow:create")
resource = Column(String(50), nullable=False, comment="资源类型workflow、agent、execution")
action = Column(String(50), nullable=False, comment="操作类型create、read、update、delete、execute")
description = Column(String(255), comment="权限描述")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
roles = relationship("Role", secondary=role_permissions, back_populates="permissions")
def __repr__(self):
return f"<Permission(id={self.id}, name={self.name}, code={self.code})>"
class WorkflowPermission(Base):
"""工作流权限表(细粒度权限控制)"""
__tablename__ = "workflow_permissions"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="权限ID")
workflow_id = Column(CHAR(36), ForeignKey("workflows.id", ondelete='CASCADE'), nullable=False, comment="工作流ID")
user_id = Column(CHAR(36), ForeignKey("users.id", ondelete='CASCADE'), nullable=True, comment="用户IDnull表示所有用户")
role_id = Column(CHAR(36), ForeignKey("roles.id", ondelete='CASCADE'), nullable=True, comment="角色IDnull表示所有角色")
permission_type = Column(String(20), nullable=False, comment="权限类型read/write/execute/share")
granted_by = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="授权人ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
workflow = relationship("Workflow", backref="permissions")
user = relationship("User", foreign_keys=[user_id], backref="workflow_permissions")
role = relationship("Role", backref="workflow_permissions")
grantor = relationship("User", foreign_keys=[granted_by])
def __repr__(self):
return f"<WorkflowPermission(id={self.id}, workflow_id={self.workflow_id}, permission_type={self.permission_type})>"
class AgentPermission(Base):
"""Agent权限表细粒度权限控制"""
__tablename__ = "agent_permissions"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="权限ID")
agent_id = Column(CHAR(36), ForeignKey("agents.id", ondelete='CASCADE'), nullable=False, comment="Agent ID")
user_id = Column(CHAR(36), ForeignKey("users.id", ondelete='CASCADE'), nullable=True, comment="用户IDnull表示所有用户")
role_id = Column(CHAR(36), ForeignKey("roles.id", ondelete='CASCADE'), nullable=True, comment="角色IDnull表示所有角色")
permission_type = Column(String(20), nullable=False, comment="权限类型read/write/execute/deploy")
granted_by = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="授权人ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
agent = relationship("Agent", backref="permissions")
user = relationship("User", foreign_keys=[user_id], backref="agent_permissions")
role = relationship("Role", backref="agent_permissions")
grantor = relationship("User", foreign_keys=[granted_by])
def __repr__(self):
return f"<AgentPermission(id={self.id}, agent_id={self.agent_id}, permission_type={self.permission_type})>"

View File

@@ -0,0 +1,48 @@
"""
用户模型
"""
from sqlalchemy import Column, String, DateTime, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class User(Base):
"""用户表"""
__tablename__ = "users"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="用户ID")
username = Column(String(50), unique=True, nullable=False, comment="用户名")
email = Column(String(100), unique=True, nullable=False, comment="邮箱")
password_hash = Column(String(255), nullable=False, comment="密码哈希")
role = Column(String(20), default="user", comment="角色: admin/user保留字段用于向后兼容")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# RBAC关系多对多
roles = relationship("Role", secondary="user_roles", back_populates="users")
def __repr__(self):
return f"<User(id={self.id}, username={self.username})>"
def has_permission(self, permission_code: str) -> bool:
"""检查用户是否有指定权限"""
# 如果是admin拥有所有权限
if self.role == "admin":
return True
# 检查用户的所有角色是否包含该权限
for role in self.roles:
for permission in role.permissions:
if permission.code == permission_code:
return True
return False
def has_role(self, role_name: str) -> bool:
"""检查用户是否有指定角色"""
# 如果是admin拥有所有角色
if self.role == "admin":
return True
return any(role.name == role_name for role in self.roles)

View File

@@ -0,0 +1,30 @@
"""
工作流模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class Workflow(Base):
"""工作流表"""
__tablename__ = "workflows"
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="描述")
nodes = Column(JSON, nullable=False, comment="节点配置")
edges = Column(JSON, nullable=False, comment="边配置")
version = Column(Integer, default=1, comment="版本号")
status = Column(String(20), default="draft", comment="状态: draft/published/running/stopped")
user_id = Column(CHAR(36), ForeignKey("users.id"), comment="创建者ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="workflows")
def __repr__(self):
return f"<Workflow(id={self.id}, name={self.name})>"

View File

@@ -0,0 +1,76 @@
"""
工作流模板市场模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, Boolean, Float, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class WorkflowTemplate(Base):
"""工作流模板表(用户分享的模板)"""
__tablename__ = "workflow_templates"
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="模板描述")
category = Column(String(50), comment="分类: llm/data_processing/automation/integration/other")
tags = Column(JSON, comment="标签列表")
nodes = Column(JSON, nullable=False, comment="节点配置")
edges = Column(JSON, nullable=False, comment="边配置")
thumbnail = Column(String(500), comment="缩略图URL")
is_public = Column(Boolean, default=True, comment="是否公开")
is_featured = Column(Boolean, default=False, comment="是否精选")
view_count = Column(Integer, default=0, comment="查看次数")
use_count = Column(Integer, default=0, comment="使用次数")
rating_count = Column(Integer, default=0, comment="评分次数")
rating_avg = Column(Float, default=0.0, comment="平均评分")
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="创建者ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
user = relationship("User", backref="shared_templates")
ratings = relationship("TemplateRating", back_populates="template", cascade="all, delete-orphan")
favorites = relationship("TemplateFavorite", back_populates="template", cascade="all, delete-orphan")
def __repr__(self):
return f"<WorkflowTemplate(id={self.id}, name={self.name})>"
class TemplateRating(Base):
"""模板评分表"""
__tablename__ = "template_ratings"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="评分ID")
template_id = Column(CHAR(36), ForeignKey("workflow_templates.id"), nullable=False, comment="模板ID")
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="用户ID")
rating = Column(Integer, nullable=False, comment="评分: 1-5")
comment = Column(Text, comment="评论")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
# 关系
template = relationship("WorkflowTemplate", back_populates="ratings")
user = relationship("User", backref="template_ratings")
def __repr__(self):
return f"<TemplateRating(id={self.id}, template_id={self.template_id}, rating={self.rating})>"
class TemplateFavorite(Base):
"""模板收藏表"""
__tablename__ = "template_favorites"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="收藏ID")
template_id = Column(CHAR(36), ForeignKey("workflow_templates.id"), nullable=False, comment="模板ID")
user_id = Column(CHAR(36), ForeignKey("users.id"), nullable=False, comment="用户ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
# 关系
template = relationship("WorkflowTemplate", back_populates="favorites")
user = relationship("User", backref="template_favorites")
def __repr__(self):
return f"<TemplateFavorite(id={self.id}, template_id={self.template_id}, user_id={self.user_id})>"

View File

@@ -0,0 +1,32 @@
"""
工作流版本模型
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from sqlalchemy.orm import relationship
from app.core.database import Base
import uuid
class WorkflowVersion(Base):
"""工作流版本表"""
__tablename__ = "workflow_versions"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="版本ID")
workflow_id = Column(CHAR(36), ForeignKey("workflows.id"), nullable=False, comment="工作流ID")
version = Column(Integer, nullable=False, comment="版本号")
name = Column(String(100), nullable=False, comment="工作流名称")
description = Column(Text, comment="描述")
nodes = Column(JSON, nullable=False, comment="节点配置")
edges = Column(JSON, nullable=False, comment="边配置")
status = Column(String(20), default="draft", comment="状态: draft/published/running/stopped")
created_by = Column(CHAR(36), ForeignKey("users.id"), comment="创建者ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
comment = Column(Text, comment="版本备注")
# 关系
workflow = relationship("Workflow", backref="versions")
creator = relationship("User", foreign_keys=[created_by])
def __repr__(self):
return f"<WorkflowVersion(id={self.id}, workflow_id={self.workflow_id}, version={self.version})>"