1161 lines
52 KiB
Python
1161 lines
52 KiB
Python
"""
|
|
AIFlow 数据库模型定义 - SQLAlchemy ORM
|
|
所有用户数据查询必须带 user_id 过滤实现物理隔离
|
|
"""
|
|
import uuid
|
|
from datetime import datetime, date
|
|
from sqlalchemy import (
|
|
Text,
|
|
Column, String, Integer, BigInteger, Float, Boolean,
|
|
DateTime, Date, Text, Enum, ForeignKey, Index, JSON,
|
|
DECIMAL, UniqueConstraint
|
|
)
|
|
from sqlalchemy.orm import relationship
|
|
from .database import Base
|
|
|
|
|
|
def gen_uuid() -> str:
|
|
return str(uuid.uuid4())
|
|
|
|
|
|
# ============================================================
|
|
# 用户与权限
|
|
# ============================================================
|
|
|
|
class User(Base):
|
|
__tablename__ = "users"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
username = Column(String(50), unique=True, nullable=False)
|
|
email = Column(String(100), default=None)
|
|
phone = Column(String(20), default=None)
|
|
password_hash = Column(String(255), nullable=False)
|
|
avatar = Column(String(500), default=None)
|
|
role = Column(String(10), nullable=False, default="user") # user / admin
|
|
status = Column(String(10), nullable=False, default="active") # active / banned
|
|
real_name_status = Column(String(20), nullable=False, default="unverified")
|
|
real_name = Column(String(50), default=None)
|
|
id_card = Column(String(20), default=None)
|
|
membership_plan_id = Column(String(36), default=None)
|
|
membership_level = Column(Integer, default=0)
|
|
membership_expire_at = Column(DateTime, default=None)
|
|
auto_renew = Column(Boolean, default=False)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class LoginLog(Base):
|
|
__tablename__ = "login_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
ip = Column(String(45), default=None)
|
|
user_agent = Column(String(500), default=None)
|
|
login_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class ApiKey(Base):
|
|
__tablename__ = "api_keys"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
api_key = Column(String(64), unique=True, nullable=False)
|
|
secret = Column(String(128), nullable=False)
|
|
name = Column(String(100), default=None)
|
|
status = Column(String(10), nullable=False, default="active") # active / revoked
|
|
last_used_at = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
expired_at = Column(DateTime, default=None)
|
|
description = Column(String(500), default=None, comment="密钥描述")
|
|
rate_limit = Column(Integer, default=60, comment="速率限制(请求/分钟)")
|
|
total_calls = Column(BigInteger, default=0, comment="总调用次数")
|
|
|
|
|
|
# ============================================================
|
|
# AI聊天与频道
|
|
# ============================================================
|
|
|
|
class Conversation(Base):
|
|
__tablename__ = "conversations"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
title = Column(String(200), nullable=False, default="新对话")
|
|
model_id = Column(String(36), default=None)
|
|
status = Column(String(10), nullable=False, default="active") # active / archived
|
|
pinned = Column(Boolean, default=False)
|
|
knowledge_graph_count = Column(Integer, default=0)
|
|
knowledge_graph_base_id = Column(String(64), default=None, comment="已生成的知识图谱知识库ID")
|
|
source = Column(String(32), default=None, comment="对话来源,如 wechat_bot")
|
|
ext_agent_conversation_id = Column(String(128), default=None, comment="外部Agent(Dify/Coze)会话ID,用于维持多轮上下文")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class Message(Base):
|
|
__tablename__ = "messages"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
conversation_id = Column(String(36), ForeignKey("conversations.id"), nullable=False)
|
|
role = Column(String(10), nullable=False) # user / assistant / system
|
|
content = Column(Text, nullable=False)
|
|
token_used = Column(Integer, default=0)
|
|
model_id = Column(String(36), default=None)
|
|
knowledge_ids = Column(JSON, default=None)
|
|
agent_ids = Column(JSON, default=None)
|
|
skill_ids = Column(JSON, default=None)
|
|
mcp_ids = Column(JSON, default=None, comment="该轮对话选择的MCP应用ID列表")
|
|
attachments = Column(JSON, default=None, comment="该轮对话附带的文件附件列表")
|
|
used_skills = Column(JSON, default=None, comment="该轮对话调用的进化技能名列表")
|
|
used_mcp = Column(JSON, default=None, comment="该轮对话调用的MCP应用名列表")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class Channel(Base):
|
|
__tablename__ = "channels"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
owner_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
name = Column(String(100), nullable=False)
|
|
description = Column(Text, default=None)
|
|
platform = Column(String(20), nullable=False)
|
|
webhook_url = Column(String(500), default=None)
|
|
credential = Column(JSON, default=None)
|
|
oauth_state = Column(String(500), default=None)
|
|
settings = Column(JSON, default=None)
|
|
account_name = Column(String(100), default=None)
|
|
default_agent_id = Column(String(36), default=None)
|
|
default_skill_id = Column(String(36), default=None)
|
|
knowledge_base_id = Column(String(36), default=None)
|
|
bound_model_id = Column(String(36), default=None)
|
|
features = Column(JSON, default=None)
|
|
status = Column(String(20), nullable=False, default="pending")
|
|
is_active = Column(Boolean, default=True)
|
|
last_active = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class ChannelMember(Base):
|
|
__tablename__ = "channel_members"
|
|
__table_args__ = (UniqueConstraint("channel_id", "user_id"),)
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
channel_id = Column(String(36), ForeignKey("channels.id"), nullable=False)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
role = Column(String(10), nullable=False, default="member") # owner / member
|
|
joined_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class ChannelMessage(Base):
|
|
__tablename__ = "channel_messages"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
channel_id = Column(String(36), ForeignKey("channels.id"), nullable=False)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
role = Column(String(10), nullable=False)
|
|
content = Column(Text, nullable=False)
|
|
token_used = Column(Integer, default=0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 知识库
|
|
# ============================================================
|
|
|
|
class KnowledgeBase(Base):
|
|
__tablename__ = "knowledge_bases"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
name = Column(String(200), nullable=False)
|
|
description = Column(Text, default=None)
|
|
directory_path = Column(String(500), default="/")
|
|
document_count = Column(Integer, default=0)
|
|
knowledge_graph_count = Column(Integer, default=0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
is_official = Column(Boolean, default=False)
|
|
status = Column(String(20), default="active")
|
|
external_service_id = Column(String(36), default=None)
|
|
external_id = Column(String(100), default=None)
|
|
external_sync_status = Column(String(20), default="none")
|
|
external_config = Column(JSON, default=None)
|
|
|
|
|
|
class KnowledgeDirectory(Base):
|
|
__tablename__ = "knowledge_directories"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), default=None)
|
|
parent_id = Column(String(36), default=None)
|
|
name = Column(String(200), nullable=False)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class KnowledgeDocument(Base):
|
|
__tablename__ = "knowledge_documents"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), nullable=False)
|
|
directory_id = Column(String(36), ForeignKey("knowledge_directories.id"), default=None)
|
|
filename = Column(String(255), nullable=False)
|
|
file_type = Column(String(20), nullable=False)
|
|
file_size = Column(BigInteger, default=0)
|
|
file_path = Column(String(500), default=None)
|
|
status = Column(String(20), nullable=False, default="uploading")
|
|
chunk_count = Column(Integer, default=0)
|
|
error_message = Column(Text, default=None)
|
|
content = Column(Text, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
|
|
|
|
class KnowledgeDocumentChunk(Base):
|
|
"""知识库文档分段表 — Stage C.1"""
|
|
__tablename__ = "knowledge_document_chunks"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
document_id = Column(String(36), ForeignKey("knowledge_documents.id"), nullable=False)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), nullable=False)
|
|
chunk_index = Column(Integer, nullable=False, default=0, comment="分段序号")
|
|
content = Column(Text, nullable=False, comment="分段文本内容")
|
|
start_char = Column(Integer, default=0, comment="起始字符位置")
|
|
end_char = Column(Integer, default=0, comment="结束字符位置")
|
|
chunk_metadata = Column(JSON, default=None, comment="分段元数据(标题、关键词等)")
|
|
token_count = Column(Integer, default=0, comment="分段token数估算")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
Index("idx_kdc_doc_id", "document_id"),
|
|
Index("idx_kdc_kb_id", "knowledge_base_id"),
|
|
)
|
|
|
|
class KnowledgeGraphNode(Base):
|
|
__tablename__ = "knowledge_graph_nodes"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), nullable=False)
|
|
source_doc_id = Column(String(36), ForeignKey("knowledge_documents.id"), default=None)
|
|
label = Column(String(500), nullable=False)
|
|
type = Column(String(50), nullable=False, comment="entity/attribute/concept/event")
|
|
properties = Column(JSON, default=None)
|
|
description = Column(Text, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class KnowledgeGraphEdge(Base):
|
|
__tablename__ = "knowledge_graph_edges"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), nullable=False)
|
|
source_node_id = Column(String(36), ForeignKey("knowledge_graph_nodes.id"), nullable=False)
|
|
target_node_id = Column(String(36), ForeignKey("knowledge_graph_nodes.id"), nullable=False)
|
|
relation = Column(String(200), nullable=False)
|
|
weight = Column(Float, default=1.0)
|
|
description = Column(Text, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class KnowledgeGraphBuildLog(Base):
|
|
__tablename__ = "knowledge_graph_build_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
knowledge_base_id = Column(String(36), ForeignKey("knowledge_bases.id"), nullable=False)
|
|
document_id = Column(String(36), ForeignKey("knowledge_documents.id"), nullable=False)
|
|
node_count = Column(Integer, default=0)
|
|
edge_count = Column(Integer, default=0)
|
|
status = Column(String(20), default="completed")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 应用市场
|
|
# ============================================================
|
|
|
|
class MarketApp(Base):
|
|
__tablename__ = "market_apps"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(200), nullable=False)
|
|
type = Column(String(10), nullable=False) # skill / agent / mcp
|
|
source = Column(String(10), nullable=False, default="user") # official / user
|
|
publisher_id = Column(String(36), ForeignKey("users.id"), default=None)
|
|
publisher_name = Column(String(100), default=None)
|
|
description = Column(Text, default=None)
|
|
icon = Column(String(500), default=None)
|
|
tutorial = Column(Text, default=None)
|
|
price = Column(DECIMAL(10, 2), nullable=False, default=0.00)
|
|
is_member_free = Column(Boolean, default=False)
|
|
join_promotion = Column(Boolean, default=False)
|
|
status = Column(String(10), nullable=False, default="pending") # pending / published / removed
|
|
rating_avg = Column(DECIMAL(3, 2), default=0.00)
|
|
review_count = Column(Integer, default=0)
|
|
install_count = Column(Integer, default=0)
|
|
skill_content = Column(Text, default=None)
|
|
mcp_transport = Column(String(20), default=None)
|
|
platform = Column(String(20), default=None, comment="Agent 接入平台:dify/n8n/coze")
|
|
capability = Column(String(20), default=None, comment="能力分类:text/thinking/vision/tool/image/audio/asr/ocr/embedding/rerank/video")
|
|
agent_endpoint = Column(String(500), default=None)
|
|
agent_api_key = Column(Text, default=None, comment="Agent 接入 API Key(3.2 起 Fernet 加密存储)")
|
|
tool_policy = Column(JSON, default=None, comment="Agent 工具/MCP 权限沙箱策略(3.1)")
|
|
orchestration = Column(JSON, default=None, comment="Agent 多Agent编排图(3.3)")
|
|
# Phase 4.1: 市场安检 + 版本化 + 绿标
|
|
version = Column(String(20), default="1.0.0", comment="应用版本号(4.1)")
|
|
security_scan = Column(JSON, default=None, comment="安全扫描结果(4.1)")
|
|
dependencies = Column(JSON, default=None, comment="依赖声明(4.1)")
|
|
verified = Column(Boolean, default=False, comment="绿标/官方安检通过(4.1)")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class MarketAppVersion(Base):
|
|
"""Phase 4.1: 应用版本快照表,支持灰度回滚。"""
|
|
__tablename__ = "market_app_versions"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
app_id = Column(String(36), ForeignKey("market_apps.id"), nullable=False, index=True)
|
|
version = Column(String(20), nullable=False)
|
|
type = Column(String(10), nullable=False)
|
|
config = Column(JSON, default=None, comment="该版本完整配置快照(4.1)")
|
|
security_scan = Column(JSON, default=None, comment="该版本安检结果(4.1)")
|
|
dependencies = Column(JSON, default=None, comment="该版本依赖声明(4.1)")
|
|
created_by = Column(String(36), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class AppPurchase(Base):
|
|
__tablename__ = "app_purchases"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
app_id = Column(String(36), ForeignKey("market_apps.id"), nullable=False)
|
|
price = Column(DECIMAL(10, 2), nullable=False, default=0.00)
|
|
order_id = Column(String(36), default=None)
|
|
status = Column(String(20), nullable=False, default="purchased") # purchased / installed
|
|
installed_at = Column(DateTime, default=None)
|
|
purchased_at = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class AppReview(Base):
|
|
__tablename__ = "app_reviews"
|
|
__table_args__ = (UniqueConstraint("user_id", "app_id"),)
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
app_id = Column(String(36), ForeignKey("market_apps.id"), nullable=False)
|
|
rating = Column(Integer, nullable=False)
|
|
content = Column(Text, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class AppInstallation(Base):
|
|
__tablename__ = "app_installations"
|
|
__table_args__ = (UniqueConstraint("user_id", "app_id"),)
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
app_id = Column(String(36), ForeignKey("market_apps.id"), nullable=False)
|
|
installed_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 付费与订单
|
|
# ============================================================
|
|
|
|
class MembershipPlan(Base):
|
|
__tablename__ = "membership_plans"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
level = Column(Integer, nullable=False, default=0)
|
|
duration_type = Column(String(10), nullable=False) # month / quarter / year
|
|
price = Column(DECIMAL(10, 2), nullable=False)
|
|
daily_free_tokens = Column(Integer, default=0)
|
|
features = Column(JSON, default=None)
|
|
free_app_ids = Column(JSON, default=None)
|
|
free_model_ids = Column(JSON, default=None)
|
|
# 配额字段
|
|
max_agents = Column(Integer, default=5)
|
|
max_workflows = Column(Integer, default=3)
|
|
max_knowledge_bases = Column(Integer, default=2)
|
|
max_storage_mb = Column(Integer, default=1024)
|
|
api_calls_per_day = Column(Integer, default=100)
|
|
api_calls_per_min = Column(Integer, default=10)
|
|
# 权限字段
|
|
can_publish_apps = Column(Boolean, default=False)
|
|
can_create_api_keys = Column(Boolean, default=False)
|
|
can_use_workflow = Column(Boolean, default=False)
|
|
can_use_mcp = Column(Boolean, default=False)
|
|
can_use_code_exec = Column(Boolean, default=False)
|
|
can_use_privacy_mode = Column(Boolean, default=False)
|
|
can_use_dag = Column(Boolean, default=False)
|
|
allowed_model_tiers = Column(JSON, default=None)
|
|
permissions = Column(JSON, default=None)
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class MembershipSubscription(Base):
|
|
__tablename__ = "membership_subscriptions"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
plan_id = Column(String(36), ForeignKey("membership_plans.id"), nullable=False)
|
|
order_id = Column(String(36), default=None)
|
|
start_at = Column(DateTime, nullable=False)
|
|
end_at = Column(DateTime, nullable=False)
|
|
auto_renew = Column(Boolean, default=False)
|
|
status = Column(String(15), nullable=False, default="active") # active / expired / downgraded
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class Order(Base):
|
|
__tablename__ = "orders"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
order_type = Column(String(15), nullable=False) # membership / service / app
|
|
item_id = Column(String(36), default=None)
|
|
item_name = Column(String(200), default=None)
|
|
amount = Column(DECIMAL(10, 2), nullable=False)
|
|
coupon_id = Column(String(36), default=None)
|
|
discount_amount = Column(DECIMAL(10, 2), default=0.00)
|
|
payment_method = Column(String(10), default=None) # wechat / alipay
|
|
payment_id = Column(String(200), default=None)
|
|
status = Column(String(15), nullable=False, default="pending") # pending / paid / refunded / cancelled
|
|
paid_at = Column(DateTime, default=None)
|
|
receipt_number = Column(String(100), default=None)
|
|
receipt_type = Column(String(20), default=None)
|
|
receipt_title = Column(String(200), default=None)
|
|
receipt_tax_number = Column(String(50), default=None)
|
|
receipt_issued_at = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class Coupon(Base):
|
|
__tablename__ = "coupons"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
code = Column(String(50), unique=True, nullable=False)
|
|
type = Column(String(10), nullable=False) # fixed / percent
|
|
value = Column(DECIMAL(10, 2), nullable=False)
|
|
min_amount = Column(DECIMAL(10, 2), default=0.00)
|
|
valid_from = Column(DateTime, nullable=False)
|
|
valid_to = Column(DateTime, nullable=False)
|
|
total_count = Column(Integer, default=None)
|
|
used_count = Column(Integer, default=0)
|
|
status = Column(String(10), nullable=False, default="active") # active / expired / disabled
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class UserCoupon(Base):
|
|
__tablename__ = "user_coupons"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
coupon_id = Column(String(36), ForeignKey("coupons.id"), nullable=False)
|
|
status = Column(String(10), nullable=False, default="unused") # unused / used / expired
|
|
used_at = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class ValueAddedService(Base):
|
|
__tablename__ = "value_added_services"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(200), nullable=False)
|
|
description = Column(Text, default=None)
|
|
price = Column(DECIMAL(10, 2), nullable=False)
|
|
type = Column(String(20), nullable=False) # app_custom / platform_proxy / data_custom / private_project
|
|
features = Column(JSON, default=None) # 服务特性
|
|
status = Column(String(10), nullable=False, default="active") # active / inactive / deleted
|
|
assigned_agent_id = Column(String(36), default=None) # 应用定制服务绑定的Agent(市场应用ID)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class CustomServiceOrder(Base):
|
|
__tablename__ = "custom_service_orders"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
service_id = Column(String(36), default=None)
|
|
service_type = Column(String(10), nullable=False)
|
|
description = Column(Text, default=None)
|
|
status = Column(String(15), nullable=False, default="pending")
|
|
price = Column(DECIMAL(10, 2), default=0.00)
|
|
order_id = Column(String(36), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class CustomServiceRequest(Base):
|
|
"""增值服务工单表 - 用于数据定制服务和私有化项目服务"""
|
|
__tablename__ = "custom_service_requests"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
service_id = Column(String(36), ForeignKey("value_added_services.id"), nullable=False)
|
|
request_type = Column(String(20), nullable=False) # data_custom / private_project
|
|
title = Column(String(200), nullable=False)
|
|
description = Column(Text, default=None)
|
|
requirements = Column(JSON, default=None) # 需求详情JSON
|
|
status = Column(String(20), nullable=False, default="pending") # pending / processing / completed / rejected
|
|
assigned_agent_id = Column(String(36), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# Token与计费
|
|
# ============================================================
|
|
|
|
class ModelProvider(Base):
|
|
__tablename__ = "model_providers"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
protocol = Column(String(30), nullable=False, default="openai_compatible")
|
|
api_key = Column(String(255), default=None)
|
|
api_base_url = Column(String(500), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class AIModel(Base):
|
|
__tablename__ = "models"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
provider_id = Column(String(36), ForeignKey("model_providers.id"), nullable=False)
|
|
name = Column(String(100), nullable=False)
|
|
display_name = Column(String(200), default=None, comment="display name")
|
|
api_key = Column(String(255), default=None)
|
|
endpoint = Column(String(500), default=None)
|
|
capabilities = Column(JSON, default=None)
|
|
timeout = Column(Integer, default=60)
|
|
status = Column(String(10), nullable=False, default="paid") # free / paid
|
|
price_per_million_tokens = Column(DECIMAL(10, 4), nullable=False, default=0.0000)
|
|
is_enabled = Column(Boolean, default=True)
|
|
is_default = Column(Boolean, default=False) # 全局默认模型
|
|
total_calls = Column(BigInteger, default=0)
|
|
total_tokens = Column(BigInteger, default=0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class TokenUsageLog(Base):
|
|
__tablename__ = "token_usage_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
model_id = Column(String(36), default=None)
|
|
model_name = Column(String(100), default=None)
|
|
app_id = Column(String(36), default=None)
|
|
app_name = Column(String(200), default=None)
|
|
conversation_id = Column(String(36), default=None)
|
|
trace_id = Column(String(64), default=None)
|
|
prompt_tokens = Column(Integer, default=0)
|
|
completion_tokens = Column(Integer, default=0)
|
|
total_tokens = Column(Integer, default=0)
|
|
cost = Column(DECIMAL(10, 6), default=0.000000)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class TokenBalance(Base):
|
|
__tablename__ = "token_balances"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), unique=True, nullable=False)
|
|
total_consumed = Column(BigInteger, default=0)
|
|
balance = Column(BigInteger, default=0)
|
|
daily_free_used = Column(BigInteger, default=0)
|
|
daily_free_date = Column(Date, default=None)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 通知与日志
|
|
# ============================================================
|
|
|
|
class Notification(Base):
|
|
__tablename__ = "notifications"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
type = Column(String(15), nullable=False)
|
|
title = Column(String(200), nullable=False)
|
|
content = Column(Text, default=None)
|
|
is_read = Column(Boolean, default=False)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class OperationLog(Base):
|
|
__tablename__ = "operation_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), nullable=False)
|
|
username = Column(String(50), default=None)
|
|
action = Column(String(100), nullable=False)
|
|
target = Column(String(100), default=None)
|
|
target_id = Column(String(36), default=None)
|
|
detail = Column(Text, default=None)
|
|
ip = Column(String(45), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class AuditLog(Base):
|
|
__tablename__ = "audit_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
admin_id = Column(String(36), nullable=False)
|
|
admin_name = Column(String(50), default=None)
|
|
action = Column(String(100), nullable=False)
|
|
target_type = Column(String(50), default=None)
|
|
target_id = Column(String(36), default=None)
|
|
detail = Column(Text, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class RiskRule(Base):
|
|
__tablename__ = "risk_rules"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
type = Column(String(15), nullable=False)
|
|
threshold = Column(Integer, default=0)
|
|
duration = Column(Integer, default=3600)
|
|
is_enabled = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 系统配置
|
|
# ============================================================
|
|
|
|
class SiteSetting(Base):
|
|
__tablename__ = "site_settings"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
key = Column(String(100), unique=True, nullable=False)
|
|
value = Column(Text, default=None)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class EmailConfig(Base):
|
|
__tablename__ = "email_configs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
smtp_host = Column(String(200), nullable=False)
|
|
smtp_port = Column(Integer, nullable=False, default=587)
|
|
username = Column(String(200), nullable=False)
|
|
password = Column(String(200), nullable=False)
|
|
from_address = Column(String(200), nullable=False)
|
|
use_tls = Column(Boolean, default=True)
|
|
use_ssl = Column(Boolean, default=False)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class SmsConfig(Base):
|
|
__tablename__ = "sms_configs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
provider = Column(String(50), nullable=False)
|
|
api_key = Column(String(200), nullable=False)
|
|
api_secret = Column(String(200), nullable=False)
|
|
sign_name = Column(String(100), default=None)
|
|
template_code = Column(String(100), default=None)
|
|
# 短信宝 (SMSBao) 字段
|
|
username = Column(String(100), default=None) # 短信宝用户名 u
|
|
password = Column(String(200), default=None) # 短信宝密码(明文存储,发送时 MD5 32位)
|
|
goods_id = Column(String(100), default=None) # 短信宝专属通道产品 ID g
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class PaymentConfig(Base):
|
|
__tablename__ = "payment_configs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
type = Column(String(10), nullable=False) # wechat / alipay
|
|
app_id = Column(String(100), nullable=False)
|
|
merchant_id = Column(String(100), default=None) # 微信: 商户号
|
|
api_key = Column(String(255), nullable=False) # 微信: APIv2密钥 / 支付宝: 应用私钥
|
|
api_v3_key = Column(String(255), default=None) # 微信: APIv3密钥
|
|
cert_path = Column(String(500), default=None) # 微信: 证书路径
|
|
cert_serial_no = Column(String(200), default=None) # 微信: 证书序列号
|
|
alipay_public_key = Column(Text, default=None) # 支付宝: 支付宝公钥
|
|
app_private_key = Column(Text, default=None) # 支付宝: 应用私钥
|
|
gateway_url = Column(String(500), default=None) # 支付宝: 网关地址
|
|
notify_url = Column(String(500), default=None) # 支付回调通知地址
|
|
return_url = Column(String(500), default=None) # 支付宝: 同步跳转地址
|
|
status = Column(String(10), nullable=False, default="inactive") # active / inactive
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class RegisterSetting(Base):
|
|
__tablename__ = "register_settings"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
phone_required = Column(Boolean, default=True)
|
|
phone_sms_required = Column(Boolean, default=True)
|
|
email_required = Column(Boolean, default=True)
|
|
email_verify_required = Column(Boolean, default=True)
|
|
real_name_required = Column(Boolean, default=False)
|
|
aliyun_access_key = Column(String(200), default=None)
|
|
aliyun_secret_key = Column(String(200), default=None)
|
|
aliyun_endpoint = Column(String(200), default=None)
|
|
sms_sign_name = Column(String(100), default=None)
|
|
sms_template_code = Column(String(50), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 广告位
|
|
# ============================================================
|
|
|
|
class AdBanner(Base):
|
|
__tablename__ = "ad_banners"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
title = Column(String(200), nullable=False)
|
|
image_url = Column(String(500), default=None)
|
|
link_app_id = Column(String(36), default=None)
|
|
link_app_name = Column(String(200), default=None)
|
|
sort_order = Column(Integer, default=0)
|
|
click_count = Column(Integer, default=0)
|
|
status = Column(String(10), nullable=False, default="active") # active / inactive
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 资产管理
|
|
# ============================================================
|
|
|
|
class AssetCategory(Base):
|
|
__tablename__ = "asset_categories"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
type = Column(String(10), nullable=False)
|
|
icon = Column(String(200), default=None)
|
|
color = Column(String(20), default=None)
|
|
is_default = Column(Boolean, default=False)
|
|
user_id = Column(String(36), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class Asset(Base):
|
|
__tablename__ = "assets"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
name = Column(String(200), nullable=False)
|
|
category = Column(String(10), nullable=False)
|
|
sub_category = Column(String(50), default=None)
|
|
file_type = Column(String(50), default=None)
|
|
size = Column(BigInteger, default=0)
|
|
description = Column(Text, default=None)
|
|
cover_url = Column(String(500), default=None)
|
|
url = Column(String(500), default=None)
|
|
content = Column(Text, default=None)
|
|
novel_meta = Column(JSON, default=None)
|
|
status = Column(String(10), nullable=False, default="active") # active / deleted
|
|
knowledge_doc_id = Column(String(36), default=None, comment="关联的知识库文档ID(由知识库同步资产时写入)")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class NovelChapter(Base):
|
|
__tablename__ = "novel_chapters"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
asset_id = Column(String(36), ForeignKey("assets.id"), nullable=False)
|
|
title = Column(String(200), nullable=False)
|
|
word_count = Column(Integer, default=0)
|
|
sort_order = Column(Integer, default=0)
|
|
content = Column(Text(length=4294967295), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# 预留扩展
|
|
# ============================================================
|
|
|
|
class Team(Base):
|
|
__tablename__ = "teams"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
owner_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
name = Column(String(100), nullable=False)
|
|
description = Column(Text, default=None)
|
|
status = Column(String(10), nullable=False, default="active")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class Referral(Base):
|
|
__tablename__ = "referrals"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
referrer_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
referee_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
referral_code = Column(String(50), default=None)
|
|
status = Column(String(10), nullable=False, default="pending")
|
|
commission_rate = Column(DECIMAL(5, 2), default=0.00)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class OpenApiClient(Base):
|
|
__tablename__ = "open_api_clients"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
name = Column(String(100), nullable=False)
|
|
client_id = Column(String(64), unique=True, nullable=False)
|
|
client_secret = Column(String(128), nullable=False)
|
|
allowed_models = Column(JSON, default=None)
|
|
rate_limit = Column(Integer, default=60)
|
|
status = Column(String(10), nullable=False, default="active")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
total_calls = Column(BigInteger, default=0, comment="总调用次数")
|
|
last_used_at = Column(DateTime, default=None, comment="最后使用时间")
|
|
|
|
|
|
# ============================================================
|
|
# API调用统计
|
|
# ============================================================
|
|
|
|
class ApiCallStat(Base):
|
|
"""API调用统计表 - 按端点聚合"""
|
|
__tablename__ = "api_call_stats"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
endpoint = Column(String(200), nullable=False)
|
|
method = Column(String(10), nullable=False)
|
|
call_count = Column(BigInteger, default=0)
|
|
total_response_time = Column(Float, default=0.0)
|
|
error_count = Column(BigInteger, default=0)
|
|
last_called_at = Column(DateTime, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("endpoint", "method", name="uk_endpoint_method"),
|
|
)
|
|
|
|
|
|
class SlowRequestLog(Base):
|
|
"""慢请求记录表"""
|
|
__tablename__ = "slow_request_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
request_id = Column(String(64), default=None)
|
|
method = Column(String(10), nullable=False)
|
|
endpoint = Column(String(500), nullable=False)
|
|
status_code = Column(Integer, default=0)
|
|
response_time = Column(Float, default=0.0)
|
|
threshold = Column(Float, default=3.0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
Index("idx_srl_created", "created_at"),
|
|
)
|
|
|
|
|
|
# ============================================================
|
|
# AI自进化引擎 - 用户进化配置
|
|
# ============================================================
|
|
class UserEvolutionConfig(Base):
|
|
__tablename__ = "user_evolution_config"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), unique=True, nullable=False, index=True)
|
|
skill_dir_path = Column(String(500), nullable=True, comment="用户Skill仓库根目录")
|
|
trajectory_dir_path = Column(String(500), nullable=True, comment="用户对话轨迹目录")
|
|
watcher_status = Column(String(20), default="stopped", comment="运行中/已停止/错误")
|
|
watcher_error = Column(String(500), nullable=True, comment="watcher异常信息")
|
|
pipeline_status = Column(String(20), default="idle", comment="流水线状态: running/idle/error")
|
|
pipeline_processed = Column(Integer, default=0, comment="已处理轨迹数")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class EvolutionSkill(Base):
|
|
__tablename__ = "evolution_skills"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, index=True)
|
|
skill_name = Column(String(200), nullable=False, comment="技能名称")
|
|
description = Column(Text, nullable=True)
|
|
tags = Column(JSON, nullable=True, comment="标签列表")
|
|
category = Column(String(100), nullable=True, comment="技能分类")
|
|
state = Column(String(20), default="baby", comment="baby/main/staging/frozen")
|
|
use_count = Column(Integer, default=0, comment="使用次数")
|
|
version = Column(Integer, default=1)
|
|
skill_md_path = Column(String(500), nullable=True, comment="SKILL.md文件路径")
|
|
git_commit_sha = Column(String(40), nullable=True)
|
|
last_used_at = Column(DateTime, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class EvolutionEvent(Base):
|
|
__tablename__ = "evolution_events"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, index=True)
|
|
skill_name = Column(String(200), nullable=False)
|
|
event_type = Column(String(50), nullable=False, comment="created/promoted/rejected/frozen/unfrozen/edited/deleted/milestone")
|
|
description = Column(Text, nullable=True)
|
|
version_before = Column(Integer, nullable=True)
|
|
version_after = Column(Integer, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
class EvolutionTrajectory(Base):
|
|
__tablename__ = "evolution_trajectories"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, index=True)
|
|
conversation_id = Column(String(36), nullable=True, comment="关联的对话ID")
|
|
file_path = Column(String(500), nullable=True, comment="轨迹文件路径")
|
|
status = Column(String(20), default="discovered", comment="discovered/splitting/split_done/indexed/clustering/done/error/filtered")
|
|
atom_count = Column(Integer, default=0)
|
|
token_used = Column(Integer, default=0)
|
|
error_msg = Column(String(500), nullable=True, comment="轨迹处理失败的错误信息")
|
|
retry_count = Column(Integer, default=0, comment="失败重试次数")
|
|
tasks_extracted = Column(Integer, default=0, comment="拆分的AtomTask数量")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
processed_at = Column(DateTime, nullable=True)
|
|
|
|
|
|
class SkillTrajectoryLink(Base):
|
|
"""技能-轨迹关联表:记录技能与对话轨迹的关联关系"""
|
|
__tablename__ = "skill_trajectory_links"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
skill_name = Column(String(200), nullable=False, index=True, comment="关联的技能名称")
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, index=True)
|
|
trajectory_id = Column(String(36), nullable=True, comment="关联的轨迹ID")
|
|
atom_id = Column(String(128), nullable=True, comment="原子任务ID(形如 trajectory_id_atom_N,需容纳 UUID+后缀)")
|
|
weightscore = Column(Integer, default=0, comment="关联权重分")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
# ============================================================
|
|
# AI自进化v2 - 新增表
|
|
# ============================================================
|
|
|
|
class SkillVersion(Base):
|
|
"""技能版本历史表:存储每个版本的SKILL.md完整内容,支持回滚"""
|
|
__tablename__ = "skill_versions"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
skill_name = Column(String(200), nullable=False)
|
|
version = Column(Integer, nullable=False, default=1)
|
|
skill_md_content = Column(Text(4294967295), nullable=True, comment="该版本的SKILL.md完整内容")
|
|
git_commit_sha = Column(String(40), nullable=True)
|
|
description = Column(Text, nullable=True, comment="版本变更说明")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
Index("idx_sv_user_skill", "user_id", "skill_name"),
|
|
Index("idx_sv_version", "version"),
|
|
)
|
|
|
|
|
|
class EvolutionReport(Base):
|
|
"""进化报告表:存储周报/月报"""
|
|
__tablename__ = "evolution_reports"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
report_type = Column(String(20), nullable=False, comment="weekly / monthly")
|
|
period_start = Column(Date, nullable=False)
|
|
period_end = Column(Date, nullable=False)
|
|
report_data = Column(JSON, nullable=True, comment="报告详细数据(JSON)")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
Index("idx_er_user_type", "user_id", "report_type"),
|
|
Index("idx_er_period", "period_start", "period_end"),
|
|
)
|
|
|
|
|
|
class SkillPublishRecord(Base):
|
|
"""技能市场发布记录表"""
|
|
__tablename__ = "skill_publish_records"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
skill_id = Column(String(36), nullable=False, comment="关联evolution_skills.id")
|
|
skill_name = Column(String(200), nullable=False)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
market_app_id = Column(String(36), nullable=True, comment="关联market_apps.id")
|
|
price = Column(DECIMAL(10, 2), default=0.00)
|
|
market_description = Column(Text, nullable=True)
|
|
status = Column(String(20), nullable=False, default="published", comment="published/unpublished")
|
|
published_at = Column(DateTime, default=datetime.now)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
Index("idx_spr_skill_id", "skill_id"),
|
|
Index("idx_spr_user_id", "user_id"),
|
|
Index("idx_spr_status", "status"),
|
|
)
|
|
|
|
|
|
class TeamSharedSkill(Base):
|
|
"""团队共享技能表"""
|
|
__tablename__ = "team_shared_skills"
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
team_id = Column(String(36), ForeignKey("teams.id"), nullable=False)
|
|
skill_id = Column(String(36), nullable=False, comment="关联evolution_skills.id")
|
|
skill_name = Column(String(200), nullable=False)
|
|
shared_by = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
shared_by_name = Column(String(100), nullable=True, comment="分享者昵称")
|
|
is_public = Column(Boolean, default=True, comment="团队内是否可见")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("team_id", "skill_id", name="uk_tss_team_skill"),
|
|
)
|
|
|
|
|
|
class ExternalKBService(Base):
|
|
"""外部知识库服务配置"""
|
|
__tablename__ = "external_kb_services"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(200), nullable=False)
|
|
service_type = Column(String(20), nullable=False)
|
|
api_url = Column(String(500), nullable=False)
|
|
api_key = Column(String(255), default="")
|
|
config = Column(JSON, default=None)
|
|
is_enabled = Column(Boolean, default=True)
|
|
status = Column(String(20), default="disconnected")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
class OSSStorageConfig(Base):
|
|
__tablename__ = "oss_storage_configs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(200), nullable=False)
|
|
provider = Column(String(20), nullable=False)
|
|
endpoint = Column(String(500), nullable=False)
|
|
access_key = Column(String(255), nullable=False)
|
|
secret_key = Column(String(255), nullable=False)
|
|
bucket = Column(String(200), nullable=False)
|
|
region = Column(String(100), default="")
|
|
base_path = Column(String(300), default="")
|
|
is_default = Column(Boolean, default=False)
|
|
is_enabled = Column(Boolean, default=True)
|
|
status = Column(String(20), default="disconnected")
|
|
config = Column(JSON, default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
|
|
class UserStorageQuota(Base):
|
|
__tablename__ = "user_storage_quotas"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
user_id = Column(String(36), nullable=False, unique=True)
|
|
quota_bytes = Column(BigInteger, nullable=False, default=1073741824)
|
|
used_bytes = Column(BigInteger, nullable=False, default=0)
|
|
quota_type = Column(String(20), nullable=False, default="membership")
|
|
membership_level = Column(Integer, default=0)
|
|
plan_id = Column(String(36), default=None)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class AutomatedTask(Base):
|
|
__tablename__ = "automated_tasks"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(200), nullable=False)
|
|
description = Column(Text, default="")
|
|
trigger_type = Column(String(20), nullable=False)
|
|
cron_expression = Column(String(100), default=None)
|
|
event_condition = Column(JSON, default=None)
|
|
action_type = Column(String(30), nullable=False)
|
|
action_config = Column(JSON, default=None)
|
|
is_enabled = Column(Boolean, default=True)
|
|
status = Column(String(20), default="idle")
|
|
max_retries = Column(Integer, default=3)
|
|
timeout_seconds = Column(Integer, default=300)
|
|
last_run_at = Column(DateTime, default=None)
|
|
next_run_at = Column(DateTime, default=None)
|
|
total_runs = Column(Integer, default=0)
|
|
success_runs = Column(Integer, default=0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
class TaskExecutionLog(Base):
|
|
__tablename__ = "task_execution_logs"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
task_id = Column(String(36), nullable=False)
|
|
task_name = Column(String(200), default="")
|
|
status = Column(String(20), default="running")
|
|
trigger_type = Column(String(20), default="manual")
|
|
started_at = Column(DateTime, default=None)
|
|
finished_at = Column(DateTime, default=None)
|
|
duration_ms = Column(Integer, default=0)
|
|
result_summary = Column(Text, default="")
|
|
error_message = Column(Text, default="")
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
|
|
class MCPServer(Base):
|
|
__tablename__ = "mcp_servers"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
description = Column(Text, default="")
|
|
transport_type = Column(String(20), default="stdio")
|
|
command = Column(String(500), default="")
|
|
args = Column(Text, default="")
|
|
env_vars = Column(Text, default="")
|
|
url = Column(String(500), default="")
|
|
headers = Column(Text, default="")
|
|
is_enabled = Column(Boolean, default=True)
|
|
status = Column(String(20), default="disconnected")
|
|
last_connected_at = Column(DateTime, default=None)
|
|
tools_count = Column(Integer, default=0)
|
|
resources_count = Column(Integer, default=0)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
|
|
|
|
class SmsVerificationCode(Base):
|
|
__tablename__ = "sms_verification_codes"
|
|
|
|
id = Column(String(36), primary_key=True, default=gen_uuid)
|
|
phone = Column(String(20), nullable=False, index=True)
|
|
code = Column(String(10), nullable=False)
|
|
purpose = Column(String(30), nullable=False) # register / reset_password
|
|
expires_at = Column(DateTime, nullable=False)
|
|
used = Column(Boolean, default=False)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
|
|
|
|
class ConversationSummary(Base):
|
|
__tablename__ = "conversation_summaries"
|
|
|
|
conversation_id = Column(String(64), primary_key=True)
|
|
summary_text = Column(Text, nullable=False, default="")
|
|
token_count = Column(Integer, default=0)
|
|
structured_memory = Column(JSON, default=None) # T2: Semantica 式结构化长期记忆
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|