fix: auto-fix code issues (cron)
- 修复重复导入/字段 - 修复异常处理 - 修复PEP8格式问题 - 添加类型注解
This commit is contained in:
@@ -1213,3 +1213,8 @@
|
||||
|
||||
- `/root/.openclaw/workspace/projects/insightflow/backend/workflow_manager.py:18` - 未使用的导入: urllib.parse
|
||||
- `/root/.openclaw/workspace/projects/insightflow/backend/plugin_manager.py:14` - 未使用的导入: urllib.parse
|
||||
|
||||
|
||||
## Git 提交结果
|
||||
|
||||
✅ 提交并推送成功
|
||||
|
||||
@@ -27,6 +27,7 @@ import httpx
|
||||
# Database path
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
|
||||
|
||||
|
||||
class ModelType(StrEnum):
|
||||
"""模型类型"""
|
||||
|
||||
@@ -35,6 +36,7 @@ class ModelType(StrEnum):
|
||||
SUMMARIZATION = "summarization" # 摘要
|
||||
PREDICTION = "prediction" # 预测
|
||||
|
||||
|
||||
class ModelStatus(StrEnum):
|
||||
"""模型状态"""
|
||||
|
||||
@@ -44,6 +46,7 @@ class ModelStatus(StrEnum):
|
||||
FAILED = "failed"
|
||||
ARCHIVED = "archived"
|
||||
|
||||
|
||||
class MultimodalProvider(StrEnum):
|
||||
"""多模态模型提供商"""
|
||||
|
||||
@@ -52,6 +55,7 @@ class MultimodalProvider(StrEnum):
|
||||
GEMINI = "gemini-pro-vision"
|
||||
KIMI_VL = "kimi-vl"
|
||||
|
||||
|
||||
class PredictionType(StrEnum):
|
||||
"""预测类型"""
|
||||
|
||||
@@ -60,6 +64,7 @@ class PredictionType(StrEnum):
|
||||
ENTITY_GROWTH = "entity_growth" # 实体增长预测
|
||||
RELATION_EVOLUTION = "relation_evolution" # 关系演变预测
|
||||
|
||||
|
||||
@dataclass
|
||||
class CustomModel:
|
||||
"""自定义模型"""
|
||||
@@ -79,6 +84,7 @@ class CustomModel:
|
||||
trained_at: str | None
|
||||
created_by: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class TrainingSample:
|
||||
"""训练样本"""
|
||||
@@ -90,6 +96,7 @@ class TrainingSample:
|
||||
metadata: dict
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class MultimodalAnalysis:
|
||||
"""多模态分析结果"""
|
||||
@@ -106,6 +113,7 @@ class MultimodalAnalysis:
|
||||
cost: float
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class KnowledgeGraphRAG:
|
||||
"""基于知识图谱的 RAG 配置"""
|
||||
@@ -122,6 +130,7 @@ class KnowledgeGraphRAG:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class RAGQuery:
|
||||
"""RAG 查询记录"""
|
||||
@@ -137,6 +146,7 @@ class RAGQuery:
|
||||
latency_ms: int
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PredictionModel:
|
||||
"""预测模型"""
|
||||
@@ -156,6 +166,7 @@ class PredictionModel:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PredictionResult:
|
||||
"""预测结果"""
|
||||
@@ -171,6 +182,7 @@ class PredictionResult:
|
||||
is_correct: bool | None
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SmartSummary:
|
||||
"""智能摘要"""
|
||||
@@ -188,6 +200,7 @@ class SmartSummary:
|
||||
tokens_used: int
|
||||
created_at: str
|
||||
|
||||
|
||||
class AIManager:
|
||||
"""AI 能力管理主类"""
|
||||
|
||||
@@ -1487,9 +1500,11 @@ class AIManager:
|
||||
created_at=row["created_at"],
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_ai_manager = None
|
||||
|
||||
|
||||
def get_ai_manager() -> AIManager:
|
||||
global _ai_manager
|
||||
if _ai_manager is None:
|
||||
|
||||
@@ -15,11 +15,13 @@ from enum import Enum
|
||||
|
||||
DB_PATH = os.getenv("DB_PATH", "/app/data/insightflow.db")
|
||||
|
||||
|
||||
class ApiKeyStatus(Enum):
|
||||
ACTIVE = "active"
|
||||
REVOKED = "revoked"
|
||||
EXPIRED = "expired"
|
||||
|
||||
|
||||
@dataclass
|
||||
class ApiKey:
|
||||
id: str
|
||||
@@ -37,6 +39,7 @@ class ApiKey:
|
||||
revoked_reason: str | None
|
||||
total_calls: int = 0
|
||||
|
||||
|
||||
class ApiKeyManager:
|
||||
"""API Key 管理器"""
|
||||
|
||||
@@ -522,9 +525,11 @@ class ApiKeyManager:
|
||||
total_calls=row["total_calls"],
|
||||
)
|
||||
|
||||
|
||||
# 全局实例
|
||||
_api_key_manager: ApiKeyManager | None = None
|
||||
|
||||
|
||||
def get_api_key_manager() -> ApiKeyManager:
|
||||
"""获取 API Key 管理器实例"""
|
||||
global _api_key_manager
|
||||
|
||||
@@ -11,6 +11,7 @@ from datetime import datetime, timedelta
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
|
||||
class SharePermission(Enum):
|
||||
"""分享权限级别"""
|
||||
|
||||
@@ -19,6 +20,7 @@ class SharePermission(Enum):
|
||||
EDIT = "edit" # 可编辑
|
||||
ADMIN = "admin" # 管理员
|
||||
|
||||
|
||||
class CommentTargetType(Enum):
|
||||
"""评论目标类型"""
|
||||
|
||||
@@ -27,6 +29,7 @@ class CommentTargetType(Enum):
|
||||
TRANSCRIPT = "transcript" # 转录文本评论
|
||||
PROJECT = "project" # 项目级评论
|
||||
|
||||
|
||||
class ChangeType(Enum):
|
||||
"""变更类型"""
|
||||
|
||||
@@ -36,6 +39,7 @@ class ChangeType(Enum):
|
||||
MERGE = "merge" # 合并
|
||||
SPLIT = "split" # 拆分
|
||||
|
||||
|
||||
@dataclass
|
||||
class ProjectShare:
|
||||
"""项目分享链接"""
|
||||
@@ -54,6 +58,7 @@ class ProjectShare:
|
||||
allow_download: bool # 允许下载
|
||||
allow_export: bool # 允许导出
|
||||
|
||||
|
||||
@dataclass
|
||||
class Comment:
|
||||
"""评论/批注"""
|
||||
@@ -74,6 +79,7 @@ class Comment:
|
||||
mentions: list[str] # 提及的用户
|
||||
attachments: list[dict] # 附件
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChangeRecord:
|
||||
"""变更记录"""
|
||||
@@ -95,6 +101,7 @@ class ChangeRecord:
|
||||
reverted_at: str | None # 回滚时间
|
||||
reverted_by: str | None # 回滚者
|
||||
|
||||
|
||||
@dataclass
|
||||
class TeamMember:
|
||||
"""团队成员"""
|
||||
@@ -110,6 +117,7 @@ class TeamMember:
|
||||
last_active_at: str | None # 最后活跃时间
|
||||
permissions: list[str] # 具体权限列表
|
||||
|
||||
|
||||
@dataclass
|
||||
class TeamSpace:
|
||||
"""团队空间"""
|
||||
@@ -124,6 +132,7 @@ class TeamSpace:
|
||||
project_count: int
|
||||
settings: dict[str, Any] # 团队设置
|
||||
|
||||
|
||||
class CollaborationManager:
|
||||
"""协作管理主类"""
|
||||
|
||||
@@ -982,9 +991,11 @@ class CollaborationManager:
|
||||
)
|
||||
self.db.conn.commit()
|
||||
|
||||
|
||||
# 全局协作管理器实例
|
||||
_collaboration_manager = None
|
||||
|
||||
|
||||
def get_collaboration_manager(db_manager=None) -> None:
|
||||
"""获取协作管理器单例"""
|
||||
global _collaboration_manager
|
||||
|
||||
@@ -14,6 +14,7 @@ from datetime import datetime
|
||||
|
||||
DB_PATH = os.getenv("DB_PATH", "/app/data/insightflow.db")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Project:
|
||||
id: str
|
||||
@@ -22,6 +23,7 @@ class Project:
|
||||
created_at: str = ""
|
||||
updated_at: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class Entity:
|
||||
id: str
|
||||
@@ -42,6 +44,7 @@ class Entity:
|
||||
if self.attributes is None:
|
||||
self.attributes = {}
|
||||
|
||||
|
||||
@dataclass
|
||||
class AttributeTemplate:
|
||||
"""属性模板定义"""
|
||||
@@ -62,6 +65,7 @@ class AttributeTemplate:
|
||||
if self.options is None:
|
||||
self.options = []
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityAttribute:
|
||||
"""实体属性值"""
|
||||
@@ -82,6 +86,7 @@ class EntityAttribute:
|
||||
if self.options is None:
|
||||
self.options = []
|
||||
|
||||
|
||||
@dataclass
|
||||
class AttributeHistory:
|
||||
"""属性变更历史"""
|
||||
@@ -95,6 +100,7 @@ class AttributeHistory:
|
||||
changed_at: str = ""
|
||||
change_reason: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityMention:
|
||||
id: str
|
||||
@@ -105,6 +111,7 @@ class EntityMention:
|
||||
text_snippet: str
|
||||
confidence: float = 1.0
|
||||
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self, db_path: str = DB_PATH):
|
||||
self.db_path = db_path
|
||||
@@ -1385,9 +1392,11 @@ class DatabaseManager:
|
||||
conn.close()
|
||||
return stats
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_db_manager = None
|
||||
|
||||
|
||||
def get_db_manager() -> DatabaseManager:
|
||||
global _db_manager
|
||||
if _db_manager is None:
|
||||
|
||||
@@ -21,6 +21,7 @@ from enum import StrEnum
|
||||
# Database path
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
|
||||
|
||||
|
||||
class SDKLanguage(StrEnum):
|
||||
"""SDK 语言类型"""
|
||||
|
||||
@@ -31,6 +32,7 @@ class SDKLanguage(StrEnum):
|
||||
JAVA = "java"
|
||||
RUST = "rust"
|
||||
|
||||
|
||||
class SDKStatus(StrEnum):
|
||||
"""SDK 状态"""
|
||||
|
||||
@@ -40,6 +42,7 @@ class SDKStatus(StrEnum):
|
||||
DEPRECATED = "deprecated" # 已弃用
|
||||
ARCHIVED = "archived" # 已归档
|
||||
|
||||
|
||||
class TemplateCategory(StrEnum):
|
||||
"""模板分类"""
|
||||
|
||||
@@ -50,6 +53,7 @@ class TemplateCategory(StrEnum):
|
||||
TECH = "tech" # 科技
|
||||
GENERAL = "general" # 通用
|
||||
|
||||
|
||||
class TemplateStatus(StrEnum):
|
||||
"""模板状态"""
|
||||
|
||||
@@ -59,6 +63,7 @@ class TemplateStatus(StrEnum):
|
||||
PUBLISHED = "published" # 已发布
|
||||
UNLISTED = "unlisted" # 未列出
|
||||
|
||||
|
||||
class PluginStatus(StrEnum):
|
||||
"""插件状态"""
|
||||
|
||||
@@ -69,6 +74,7 @@ class PluginStatus(StrEnum):
|
||||
PUBLISHED = "published" # 已发布
|
||||
SUSPENDED = "suspended" # 已暂停
|
||||
|
||||
|
||||
class PluginCategory(StrEnum):
|
||||
"""插件分类"""
|
||||
|
||||
@@ -79,6 +85,7 @@ class PluginCategory(StrEnum):
|
||||
SECURITY = "security" # 安全
|
||||
CUSTOM = "custom" # 自定义
|
||||
|
||||
|
||||
class DeveloperStatus(StrEnum):
|
||||
"""开发者认证状态"""
|
||||
|
||||
@@ -88,6 +95,7 @@ class DeveloperStatus(StrEnum):
|
||||
CERTIFIED = "certified" # 已认证(高级)
|
||||
SUSPENDED = "suspended" # 已暂停
|
||||
|
||||
|
||||
@dataclass
|
||||
class SDKRelease:
|
||||
"""SDK 发布"""
|
||||
@@ -113,6 +121,7 @@ class SDKRelease:
|
||||
published_at: str | None
|
||||
created_by: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SDKVersion:
|
||||
"""SDK 版本历史"""
|
||||
@@ -129,6 +138,7 @@ class SDKVersion:
|
||||
download_count: int
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class TemplateMarketItem:
|
||||
"""模板市场项目"""
|
||||
@@ -160,6 +170,7 @@ class TemplateMarketItem:
|
||||
updated_at: str
|
||||
published_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class TemplateReview:
|
||||
"""模板评价"""
|
||||
@@ -175,6 +186,7 @@ class TemplateReview:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PluginMarketItem:
|
||||
"""插件市场项目"""
|
||||
@@ -213,6 +225,7 @@ class PluginMarketItem:
|
||||
reviewed_at: str | None
|
||||
review_notes: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PluginReview:
|
||||
"""插件评价"""
|
||||
@@ -228,6 +241,7 @@ class PluginReview:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeveloperProfile:
|
||||
"""开发者档案"""
|
||||
@@ -251,6 +265,7 @@ class DeveloperProfile:
|
||||
updated_at: str
|
||||
verified_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeveloperRevenue:
|
||||
"""开发者收益"""
|
||||
@@ -268,6 +283,7 @@ class DeveloperRevenue:
|
||||
transaction_id: str
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class CodeExample:
|
||||
"""代码示例"""
|
||||
@@ -290,6 +306,7 @@ class CodeExample:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class APIDocumentation:
|
||||
"""API 文档生成记录"""
|
||||
@@ -303,6 +320,7 @@ class APIDocumentation:
|
||||
generated_at: str
|
||||
generated_by: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeveloperPortalConfig:
|
||||
"""开发者门户配置"""
|
||||
@@ -326,6 +344,7 @@ class DeveloperPortalConfig:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
class DeveloperEcosystemManager:
|
||||
"""开发者生态系统管理主类"""
|
||||
|
||||
@@ -2031,9 +2050,11 @@ class DeveloperEcosystemManager:
|
||||
updated_at=row["updated_at"],
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_developer_ecosystem_manager = None
|
||||
|
||||
|
||||
def get_developer_ecosystem_manager() -> DeveloperEcosystemManager:
|
||||
"""获取开发者生态系统管理器单例"""
|
||||
global _developer_ecosystem_manager
|
||||
|
||||
@@ -7,6 +7,7 @@ Document Processor - Phase 3
|
||||
import io
|
||||
import os
|
||||
|
||||
|
||||
class DocumentProcessor:
|
||||
"""文档处理器 - 提取 PDF/DOCX 文本"""
|
||||
|
||||
@@ -155,6 +156,7 @@ class DocumentProcessor:
|
||||
ext = os.path.splitext(filename.lower())[1]
|
||||
return ext in self.supported_formats
|
||||
|
||||
|
||||
# 简单的文本提取器(不需要外部依赖)
|
||||
class SimpleTextExtractor:
|
||||
"""简单的文本提取器,用于测试"""
|
||||
@@ -171,6 +173,7 @@ class SimpleTextExtractor:
|
||||
|
||||
return content.decode("latin-1", errors="ignore")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试
|
||||
processor = DocumentProcessor()
|
||||
|
||||
@@ -21,6 +21,7 @@ from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SSOProvider(StrEnum):
|
||||
"""SSO 提供商类型"""
|
||||
|
||||
@@ -32,6 +33,7 @@ class SSOProvider(StrEnum):
|
||||
GOOGLE = "google" # Google Workspace
|
||||
CUSTOM_SAML = "custom_saml" # 自定义 SAML
|
||||
|
||||
|
||||
class SSOStatus(StrEnum):
|
||||
"""SSO 配置状态"""
|
||||
|
||||
@@ -40,6 +42,7 @@ class SSOStatus(StrEnum):
|
||||
ACTIVE = "active" # 已启用
|
||||
ERROR = "error" # 配置错误
|
||||
|
||||
|
||||
class SCIMSyncStatus(StrEnum):
|
||||
"""SCIM 同步状态"""
|
||||
|
||||
@@ -48,6 +51,7 @@ class SCIMSyncStatus(StrEnum):
|
||||
SUCCESS = "success" # 同步成功
|
||||
FAILED = "failed" # 同步失败
|
||||
|
||||
|
||||
class AuditLogExportFormat(StrEnum):
|
||||
"""审计日志导出格式"""
|
||||
|
||||
@@ -56,6 +60,7 @@ class AuditLogExportFormat(StrEnum):
|
||||
PDF = "pdf"
|
||||
XLSX = "xlsx"
|
||||
|
||||
|
||||
class DataRetentionAction(StrEnum):
|
||||
"""数据保留策略动作"""
|
||||
|
||||
@@ -63,6 +68,7 @@ class DataRetentionAction(StrEnum):
|
||||
DELETE = "delete" # 删除
|
||||
ANONYMIZE = "anonymize" # 匿名化
|
||||
|
||||
|
||||
class ComplianceStandard(StrEnum):
|
||||
"""合规标准"""
|
||||
|
||||
@@ -72,6 +78,7 @@ class ComplianceStandard(StrEnum):
|
||||
HIPAA = "hipaa"
|
||||
PCI_DSS = "pci_dss"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SSOConfig:
|
||||
"""SSO 配置数据类"""
|
||||
@@ -104,6 +111,7 @@ class SSOConfig:
|
||||
last_tested_at: datetime | None
|
||||
last_error: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SCIMConfig:
|
||||
"""SCIM 配置数据类"""
|
||||
@@ -128,6 +136,7 @@ class SCIMConfig:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class SCIMUser:
|
||||
"""SCIM 用户数据类"""
|
||||
@@ -147,6 +156,7 @@ class SCIMUser:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class AuditLogExport:
|
||||
"""审计日志导出记录"""
|
||||
@@ -171,6 +181,7 @@ class AuditLogExport:
|
||||
completed_at: datetime | None
|
||||
error_message: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class DataRetentionPolicy:
|
||||
"""数据保留策略"""
|
||||
@@ -198,6 +209,7 @@ class DataRetentionPolicy:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class DataRetentionJob:
|
||||
"""数据保留任务"""
|
||||
@@ -215,6 +227,7 @@ class DataRetentionJob:
|
||||
details: dict[str, Any]
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class SAMLAuthRequest:
|
||||
"""SAML 认证请求"""
|
||||
@@ -229,6 +242,7 @@ class SAMLAuthRequest:
|
||||
used: bool
|
||||
used_at: datetime | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SAMLAuthResponse:
|
||||
"""SAML 认证响应"""
|
||||
@@ -245,6 +259,7 @@ class SAMLAuthResponse:
|
||||
processed_at: datetime | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class EnterpriseManager:
|
||||
"""企业级功能管理器"""
|
||||
|
||||
@@ -2181,9 +2196,11 @@ class EnterpriseManager:
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# 全局实例
|
||||
_enterprise_manager = None
|
||||
|
||||
|
||||
def get_enterprise_manager(db_path: str = "insightflow.db") -> EnterpriseManager:
|
||||
"""获取 EnterpriseManager 单例"""
|
||||
global _enterprise_manager
|
||||
|
||||
@@ -15,6 +15,7 @@ import numpy as np
|
||||
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
|
||||
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityEmbedding:
|
||||
entity_id: str
|
||||
@@ -22,6 +23,7 @@ class EntityEmbedding:
|
||||
definition: str
|
||||
embedding: list[float]
|
||||
|
||||
|
||||
class EntityAligner:
|
||||
"""实体对齐器 - 使用 embedding 进行相似度匹配"""
|
||||
|
||||
@@ -316,6 +318,7 @@ class EntityAligner:
|
||||
|
||||
return []
|
||||
|
||||
|
||||
# 简单的字符串相似度计算(不使用 embedding)
|
||||
def simple_similarity(str1: str, str2: str) -> float:
|
||||
"""
|
||||
@@ -347,6 +350,7 @@ def simple_similarity(str1: str, str2: str) -> float:
|
||||
|
||||
return SequenceMatcher(None, s1, s2).ratio()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试
|
||||
aligner = EntityAligner()
|
||||
|
||||
@@ -36,6 +36,7 @@ try:
|
||||
except ImportError:
|
||||
REPORTLAB_AVAILABLE = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExportEntity:
|
||||
id: str
|
||||
@@ -46,6 +47,7 @@ class ExportEntity:
|
||||
mention_count: int
|
||||
attributes: dict[str, Any]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExportRelation:
|
||||
id: str
|
||||
@@ -55,6 +57,7 @@ class ExportRelation:
|
||||
confidence: float
|
||||
evidence: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExportTranscript:
|
||||
id: str
|
||||
@@ -64,6 +67,7 @@ class ExportTranscript:
|
||||
segments: list[dict]
|
||||
entity_mentions: list[dict]
|
||||
|
||||
|
||||
class ExportManager:
|
||||
"""导出管理器 - 处理各种导出需求"""
|
||||
|
||||
@@ -605,9 +609,11 @@ class ExportManager:
|
||||
|
||||
return json.dumps(data, ensure_ascii=False, indent=2)
|
||||
|
||||
|
||||
# 全局导出管理器实例
|
||||
_export_manager = None
|
||||
|
||||
|
||||
def get_export_manager(db_manager=None) -> None:
|
||||
"""获取导出管理器实例"""
|
||||
global _export_manager
|
||||
|
||||
@@ -28,6 +28,7 @@ import httpx
|
||||
# Database path
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
|
||||
|
||||
|
||||
class EventType(StrEnum):
|
||||
"""事件类型"""
|
||||
|
||||
@@ -43,6 +44,7 @@ class EventType(StrEnum):
|
||||
INVITE_ACCEPTED = "invite_accepted" # 接受邀请
|
||||
REFERRAL_REWARD = "referral_reward" # 推荐奖励
|
||||
|
||||
|
||||
class ExperimentStatus(StrEnum):
|
||||
"""实验状态"""
|
||||
|
||||
@@ -52,6 +54,7 @@ class ExperimentStatus(StrEnum):
|
||||
COMPLETED = "completed" # 已完成
|
||||
ARCHIVED = "archived" # 已归档
|
||||
|
||||
|
||||
class TrafficAllocationType(StrEnum):
|
||||
"""流量分配类型"""
|
||||
|
||||
@@ -59,6 +62,7 @@ class TrafficAllocationType(StrEnum):
|
||||
STRATIFIED = "stratified" # 分层分配
|
||||
TARGETED = "targeted" # 定向分配
|
||||
|
||||
|
||||
class EmailTemplateType(StrEnum):
|
||||
"""邮件模板类型"""
|
||||
|
||||
@@ -70,6 +74,7 @@ class EmailTemplateType(StrEnum):
|
||||
REFERRAL = "referral" # 推荐邀请
|
||||
NEWSLETTER = "newsletter" # 新闻通讯
|
||||
|
||||
|
||||
class EmailStatus(StrEnum):
|
||||
"""邮件状态"""
|
||||
|
||||
@@ -83,6 +88,7 @@ class EmailStatus(StrEnum):
|
||||
BOUNCED = "bounced" # 退信
|
||||
FAILED = "failed" # 失败
|
||||
|
||||
|
||||
class WorkflowTriggerType(StrEnum):
|
||||
"""工作流触发类型"""
|
||||
|
||||
@@ -94,6 +100,7 @@ class WorkflowTriggerType(StrEnum):
|
||||
MILESTONE = "milestone" # 里程碑
|
||||
CUSTOM_EVENT = "custom_event" # 自定义事件
|
||||
|
||||
|
||||
class ReferralStatus(StrEnum):
|
||||
"""推荐状态"""
|
||||
|
||||
@@ -102,6 +109,7 @@ class ReferralStatus(StrEnum):
|
||||
REWARDED = "rewarded" # 已奖励
|
||||
EXPIRED = "expired" # 已过期
|
||||
|
||||
|
||||
@dataclass
|
||||
class AnalyticsEvent:
|
||||
"""分析事件"""
|
||||
@@ -120,6 +128,7 @@ class AnalyticsEvent:
|
||||
utm_medium: str | None
|
||||
utm_campaign: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class UserProfile:
|
||||
"""用户画像"""
|
||||
@@ -139,6 +148,7 @@ class UserProfile:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Funnel:
|
||||
"""转化漏斗"""
|
||||
@@ -151,6 +161,7 @@ class Funnel:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class FunnelAnalysis:
|
||||
"""漏斗分析结果"""
|
||||
@@ -163,6 +174,7 @@ class FunnelAnalysis:
|
||||
overall_conversion: float # 总体转化率
|
||||
drop_off_points: list[dict] # 流失点
|
||||
|
||||
|
||||
@dataclass
|
||||
class Experiment:
|
||||
"""A/B 测试实验"""
|
||||
@@ -187,6 +199,7 @@ class Experiment:
|
||||
updated_at: datetime
|
||||
created_by: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExperimentResult:
|
||||
"""实验结果"""
|
||||
@@ -204,6 +217,7 @@ class ExperimentResult:
|
||||
uplift: float # 提升幅度
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class EmailTemplate:
|
||||
"""邮件模板"""
|
||||
@@ -224,6 +238,7 @@ class EmailTemplate:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class EmailCampaign:
|
||||
"""邮件营销活动"""
|
||||
@@ -245,6 +260,7 @@ class EmailCampaign:
|
||||
completed_at: datetime | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class EmailLog:
|
||||
"""邮件发送记录"""
|
||||
@@ -266,6 +282,7 @@ class EmailLog:
|
||||
error_message: str | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class AutomationWorkflow:
|
||||
"""自动化工作流"""
|
||||
@@ -282,6 +299,7 @@ class AutomationWorkflow:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReferralProgram:
|
||||
"""推荐计划"""
|
||||
@@ -301,6 +319,7 @@ class ReferralProgram:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Referral:
|
||||
"""推荐记录"""
|
||||
@@ -321,6 +340,7 @@ class Referral:
|
||||
expires_at: datetime
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class TeamIncentive:
|
||||
"""团队升级激励"""
|
||||
@@ -338,6 +358,7 @@ class TeamIncentive:
|
||||
is_active: bool
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class GrowthManager:
|
||||
"""运营与增长管理主类"""
|
||||
|
||||
@@ -2126,9 +2147,11 @@ class GrowthManager:
|
||||
created_at=row["created_at"],
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_growth_manager = None
|
||||
|
||||
|
||||
def get_growth_manager() -> GrowthManager:
|
||||
global _growth_manager
|
||||
if _growth_manager is None:
|
||||
|
||||
@@ -33,6 +33,7 @@ try:
|
||||
except ImportError:
|
||||
PYTESSERACT_AVAILABLE = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImageEntity:
|
||||
"""图片中检测到的实体"""
|
||||
@@ -42,6 +43,7 @@ class ImageEntity:
|
||||
confidence: float
|
||||
bbox: tuple[int, int, int, int] | None = None # (x, y, width, height)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImageRelation:
|
||||
"""图片中检测到的关系"""
|
||||
@@ -51,6 +53,7 @@ class ImageRelation:
|
||||
relation_type: str
|
||||
confidence: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImageProcessingResult:
|
||||
"""图片处理结果"""
|
||||
@@ -66,6 +69,7 @@ class ImageProcessingResult:
|
||||
success: bool
|
||||
error_message: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class BatchProcessingResult:
|
||||
"""批量图片处理结果"""
|
||||
@@ -75,6 +79,7 @@ class BatchProcessingResult:
|
||||
success_count: int
|
||||
failed_count: int
|
||||
|
||||
|
||||
class ImageProcessor:
|
||||
"""图片处理器 - 处理各种类型图片"""
|
||||
|
||||
@@ -548,9 +553,11 @@ class ImageProcessor:
|
||||
print(f"Thumbnail generation error: {e}")
|
||||
return image_data
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_image_processor = None
|
||||
|
||||
|
||||
def get_image_processor(temp_dir: str = None) -> ImageProcessor:
|
||||
"""获取图片处理器单例"""
|
||||
global _image_processor
|
||||
|
||||
@@ -15,6 +15,7 @@ import httpx
|
||||
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
|
||||
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
|
||||
|
||||
|
||||
class ReasoningType(Enum):
|
||||
"""推理类型"""
|
||||
|
||||
@@ -24,6 +25,7 @@ class ReasoningType(Enum):
|
||||
COMPARATIVE = "comparative" # 对比推理
|
||||
SUMMARY = "summary" # 总结推理
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReasoningResult:
|
||||
"""推理结果"""
|
||||
@@ -35,6 +37,7 @@ class ReasoningResult:
|
||||
related_entities: list[str] # 相关实体
|
||||
gaps: list[str] # 知识缺口
|
||||
|
||||
|
||||
@dataclass
|
||||
class InferencePath:
|
||||
"""推理路径"""
|
||||
@@ -44,6 +47,7 @@ class InferencePath:
|
||||
path: list[dict] # 路径上的节点和关系
|
||||
strength: float # 路径强度
|
||||
|
||||
|
||||
class KnowledgeReasoner:
|
||||
"""知识推理引擎"""
|
||||
|
||||
@@ -498,9 +502,11 @@ class KnowledgeReasoner:
|
||||
"confidence": 0.5,
|
||||
}
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_reasoner = None
|
||||
|
||||
|
||||
def get_knowledge_reasoner() -> KnowledgeReasoner:
|
||||
global _reasoner
|
||||
if _reasoner is None:
|
||||
|
||||
@@ -15,11 +15,13 @@ import httpx
|
||||
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
|
||||
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChatMessage:
|
||||
role: str
|
||||
content: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityExtractionResult:
|
||||
name: str
|
||||
@@ -27,6 +29,7 @@ class EntityExtractionResult:
|
||||
definition: str
|
||||
confidence: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class RelationExtractionResult:
|
||||
source: str
|
||||
@@ -34,6 +37,7 @@ class RelationExtractionResult:
|
||||
type: str
|
||||
confidence: float
|
||||
|
||||
|
||||
class LLMClient:
|
||||
"""Kimi API 客户端"""
|
||||
|
||||
@@ -249,9 +253,11 @@ class LLMClient:
|
||||
messages = [ChatMessage(role="user", content=prompt)]
|
||||
return await self.chat(messages, temperature=0.3)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_llm_client = None
|
||||
|
||||
|
||||
def get_llm_client() -> LLMClient:
|
||||
global _llm_client
|
||||
if _llm_client is None:
|
||||
|
||||
@@ -35,6 +35,7 @@ except ImportError:
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LanguageCode(StrEnum):
|
||||
"""支持的语言代码"""
|
||||
|
||||
@@ -51,6 +52,7 @@ class LanguageCode(StrEnum):
|
||||
AR = "ar"
|
||||
HI = "hi"
|
||||
|
||||
|
||||
class RegionCode(StrEnum):
|
||||
"""区域代码"""
|
||||
|
||||
@@ -62,6 +64,7 @@ class RegionCode(StrEnum):
|
||||
LATIN_AMERICA = "latam"
|
||||
MIDDLE_EAST = "me"
|
||||
|
||||
|
||||
class DataCenterRegion(StrEnum):
|
||||
"""数据中心区域"""
|
||||
|
||||
@@ -75,6 +78,7 @@ class DataCenterRegion(StrEnum):
|
||||
CN_NORTH = "cn-north"
|
||||
CN_EAST = "cn-east"
|
||||
|
||||
|
||||
class PaymentProvider(StrEnum):
|
||||
"""支付提供商"""
|
||||
|
||||
@@ -91,6 +95,7 @@ class PaymentProvider(StrEnum):
|
||||
SEPA = "sepa"
|
||||
UNIONPAY = "unionpay"
|
||||
|
||||
|
||||
class CalendarType(StrEnum):
|
||||
"""日历类型"""
|
||||
|
||||
@@ -102,6 +107,7 @@ class CalendarType(StrEnum):
|
||||
PERSIAN = "persian"
|
||||
BUDDHIST = "buddhist"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Translation:
|
||||
id: str
|
||||
@@ -116,6 +122,7 @@ class Translation:
|
||||
reviewed_by: str | None
|
||||
reviewed_at: datetime | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class LanguageConfig:
|
||||
code: str
|
||||
@@ -133,6 +140,7 @@ class LanguageConfig:
|
||||
first_day_of_week: int
|
||||
calendar_type: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DataCenter:
|
||||
id: str
|
||||
@@ -147,6 +155,7 @@ class DataCenter:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantDataCenterMapping:
|
||||
id: str
|
||||
@@ -158,6 +167,7 @@ class TenantDataCenterMapping:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class LocalizedPaymentMethod:
|
||||
id: str
|
||||
@@ -175,6 +185,7 @@ class LocalizedPaymentMethod:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class CountryConfig:
|
||||
code: str
|
||||
@@ -196,6 +207,7 @@ class CountryConfig:
|
||||
vat_rate: float | None
|
||||
is_active: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class TimezoneConfig:
|
||||
id: str
|
||||
@@ -206,6 +218,7 @@ class TimezoneConfig:
|
||||
region: str
|
||||
is_active: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class CurrencyConfig:
|
||||
code: str
|
||||
@@ -217,6 +230,7 @@ class CurrencyConfig:
|
||||
thousands_separator: str
|
||||
is_active: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class LocalizationSettings:
|
||||
id: str
|
||||
@@ -236,6 +250,7 @@ class LocalizationSettings:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class LocalizationManager:
|
||||
DEFAULT_LANGUAGES = {
|
||||
LanguageCode.EN: {
|
||||
@@ -731,33 +746,37 @@ class LocalizationManager:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS translations (
|
||||
id TEXT PRIMARY KEY, key TEXT NOT NULL, language TEXT NOT NULL, value TEXT NOT NULL,
|
||||
namespace TEXT DEFAULT 'common', context TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
id TEXT PRIMARY KEY, key TEXT NOT NULL, language TEXT NOT NULL,
|
||||
value TEXT NOT NULL, namespace TEXT DEFAULT 'common', context TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_reviewed INTEGER DEFAULT 0,
|
||||
reviewed_by TEXT, reviewed_at TIMESTAMP, UNIQUE(key, language, namespace)
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS language_configs (
|
||||
code TEXT PRIMARY KEY, name TEXT NOT NULL, name_local TEXT NOT NULL, is_rtl INTEGER DEFAULT 0,
|
||||
is_active INTEGER DEFAULT 1, is_default INTEGER DEFAULT 0, fallback_language TEXT,
|
||||
date_format TEXT, time_format TEXT, datetime_format TEXT, number_format TEXT,
|
||||
currency_format TEXT, first_day_of_week INTEGER DEFAULT 1, calendar_type TEXT DEFAULT 'gregorian'
|
||||
code TEXT PRIMARY KEY, name TEXT NOT NULL, name_local TEXT NOT NULL,
|
||||
is_rtl INTEGER DEFAULT 0, is_active INTEGER DEFAULT 1, is_default INTEGER DEFAULT 0,
|
||||
fallback_language TEXT, date_format TEXT, time_format TEXT, datetime_format TEXT,
|
||||
number_format TEXT, currency_format TEXT, first_day_of_week INTEGER DEFAULT 1,
|
||||
calendar_type TEXT DEFAULT 'gregorian'
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS data_centers (
|
||||
id TEXT PRIMARY KEY, region_code TEXT NOT NULL UNIQUE, name TEXT NOT NULL, location TEXT NOT NULL,
|
||||
endpoint TEXT NOT NULL, status TEXT DEFAULT 'active', priority INTEGER DEFAULT 1,
|
||||
supported_regions TEXT DEFAULT '[]', capabilities TEXT DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
id TEXT PRIMARY KEY, region_code TEXT NOT NULL UNIQUE, name TEXT NOT NULL,
|
||||
location TEXT NOT NULL, endpoint TEXT NOT NULL, status TEXT DEFAULT 'active',
|
||||
priority INTEGER DEFAULT 1, supported_regions TEXT DEFAULT '[]',
|
||||
capabilities TEXT DEFAULT '{}', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS tenant_data_center_mappings (
|
||||
id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL UNIQUE, primary_dc_id TEXT NOT NULL,
|
||||
secondary_dc_id TEXT, region_code TEXT NOT NULL, data_residency TEXT DEFAULT 'regional',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (primary_dc_id) REFERENCES data_centers(id),
|
||||
FOREIGN KEY (secondary_dc_id) REFERENCES data_centers(id)
|
||||
@@ -765,20 +784,23 @@ class LocalizationManager:
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS localized_payment_methods (
|
||||
id TEXT PRIMARY KEY, provider TEXT NOT NULL UNIQUE, name TEXT NOT NULL, name_local TEXT DEFAULT '{}',
|
||||
supported_countries TEXT DEFAULT '[]', supported_currencies TEXT DEFAULT '[]',
|
||||
is_active INTEGER DEFAULT 1, config TEXT DEFAULT '{}', icon_url TEXT, display_order INTEGER DEFAULT 0,
|
||||
id TEXT PRIMARY KEY, provider TEXT NOT NULL UNIQUE, name TEXT NOT NULL,
|
||||
name_local TEXT DEFAULT '{}', supported_countries TEXT DEFAULT '[]',
|
||||
supported_currencies TEXT DEFAULT '[]', is_active INTEGER DEFAULT 1,
|
||||
config TEXT DEFAULT '{}', icon_url TEXT, display_order INTEGER DEFAULT 0,
|
||||
min_amount REAL, max_amount REAL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS country_configs (
|
||||
code TEXT PRIMARY KEY, code3 TEXT NOT NULL, name TEXT NOT NULL, name_local TEXT DEFAULT '{}',
|
||||
region TEXT NOT NULL, default_language TEXT NOT NULL, supported_languages TEXT DEFAULT '[]',
|
||||
default_currency TEXT NOT NULL, supported_currencies TEXT DEFAULT '[]', timezone TEXT NOT NULL,
|
||||
calendar_type TEXT DEFAULT 'gregorian', date_format TEXT, time_format TEXT, number_format TEXT,
|
||||
address_format TEXT, phone_format TEXT, vat_rate REAL, is_active INTEGER DEFAULT 1
|
||||
code TEXT PRIMARY KEY, code3 TEXT NOT NULL, name TEXT NOT NULL,
|
||||
name_local TEXT DEFAULT '{}', region TEXT NOT NULL, default_language TEXT NOT NULL,
|
||||
supported_languages TEXT DEFAULT '[]', default_currency TEXT NOT NULL,
|
||||
supported_currencies TEXT DEFAULT '[]', timezone TEXT NOT NULL,
|
||||
calendar_type TEXT DEFAULT 'gregorian', date_format TEXT, time_format TEXT,
|
||||
number_format TEXT, address_format TEXT, phone_format TEXT, vat_rate REAL,
|
||||
is_active INTEGER DEFAULT 1
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
@@ -1667,8 +1689,10 @@ class LocalizationManager:
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
_localization_manager = None
|
||||
|
||||
|
||||
def get_localization_manager(db_path: str = "insightflow.db") -> LocalizationManager:
|
||||
global _localization_manager
|
||||
if _localization_manager is None:
|
||||
|
||||
714
backend/main.py
714
backend/main.py
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ try:
|
||||
except ImportError:
|
||||
NUMPY_AVAILABLE = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class MultimodalEntity:
|
||||
"""多模态实体"""
|
||||
@@ -32,6 +33,7 @@ class MultimodalEntity:
|
||||
if self.modality_features is None:
|
||||
self.modality_features = {}
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityLink:
|
||||
"""实体关联"""
|
||||
@@ -46,6 +48,7 @@ class EntityLink:
|
||||
confidence: float
|
||||
evidence: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlignmentResult:
|
||||
"""对齐结果"""
|
||||
@@ -56,6 +59,7 @@ class AlignmentResult:
|
||||
match_type: str # exact, fuzzy, embedding
|
||||
confidence: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class FusionResult:
|
||||
"""知识融合结果"""
|
||||
@@ -66,6 +70,7 @@ class FusionResult:
|
||||
source_modalities: list[str]
|
||||
confidence: float
|
||||
|
||||
|
||||
class MultimodalEntityLinker:
|
||||
"""多模态实体关联器 - 跨模态实体对齐和知识融合"""
|
||||
|
||||
@@ -507,9 +512,11 @@ class MultimodalEntityLinker:
|
||||
else 0,
|
||||
}
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_multimodal_entity_linker = None
|
||||
|
||||
|
||||
def get_multimodal_entity_linker(similarity_threshold: float = 0.85) -> MultimodalEntityLinker:
|
||||
"""获取多模态实体关联器单例"""
|
||||
global _multimodal_entity_linker
|
||||
|
||||
@@ -35,6 +35,7 @@ try:
|
||||
except ImportError:
|
||||
FFMPEG_AVAILABLE = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class VideoFrame:
|
||||
"""视频关键帧数据类"""
|
||||
@@ -52,6 +53,7 @@ class VideoFrame:
|
||||
if self.entities_detected is None:
|
||||
self.entities_detected = []
|
||||
|
||||
|
||||
@dataclass
|
||||
class VideoInfo:
|
||||
"""视频信息数据类"""
|
||||
@@ -75,6 +77,7 @@ class VideoInfo:
|
||||
if self.metadata is None:
|
||||
self.metadata = {}
|
||||
|
||||
|
||||
@dataclass
|
||||
class VideoProcessingResult:
|
||||
"""视频处理结果"""
|
||||
@@ -87,6 +90,7 @@ class VideoProcessingResult:
|
||||
success: bool
|
||||
error_message: str = ""
|
||||
|
||||
|
||||
class MultimodalProcessor:
|
||||
"""多模态处理器 - 处理视频文件"""
|
||||
|
||||
@@ -445,9 +449,11 @@ class MultimodalProcessor:
|
||||
shutil.rmtree(dir_path)
|
||||
os.makedirs(dir_path, exist_ok=True)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_multimodal_processor = None
|
||||
|
||||
|
||||
def get_multimodal_processor(temp_dir: str = None, frame_interval: int = 5) -> MultimodalProcessor:
|
||||
"""获取多模态处理器单例"""
|
||||
global _multimodal_processor
|
||||
|
||||
@@ -26,6 +26,7 @@ except ImportError:
|
||||
NEO4J_AVAILABLE = False
|
||||
logger.warning("Neo4j driver not installed. Neo4j features will be disabled.")
|
||||
|
||||
|
||||
@dataclass
|
||||
class GraphEntity:
|
||||
"""图数据库中的实体节点"""
|
||||
@@ -44,6 +45,7 @@ class GraphEntity:
|
||||
if self.properties is None:
|
||||
self.properties = {}
|
||||
|
||||
|
||||
@dataclass
|
||||
class GraphRelation:
|
||||
"""图数据库中的关系边"""
|
||||
@@ -59,6 +61,7 @@ class GraphRelation:
|
||||
if self.properties is None:
|
||||
self.properties = {}
|
||||
|
||||
|
||||
@dataclass
|
||||
class PathResult:
|
||||
"""路径查询结果"""
|
||||
@@ -68,6 +71,7 @@ class PathResult:
|
||||
length: int
|
||||
total_weight: float = 0.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommunityResult:
|
||||
"""社区发现结果"""
|
||||
@@ -77,6 +81,7 @@ class CommunityResult:
|
||||
size: int
|
||||
density: float = 0.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class CentralityResult:
|
||||
"""中心性分析结果"""
|
||||
@@ -86,6 +91,7 @@ class CentralityResult:
|
||||
score: float
|
||||
rank: int = 0
|
||||
|
||||
|
||||
class Neo4jManager:
|
||||
"""Neo4j 图数据库管理器"""
|
||||
|
||||
@@ -962,9 +968,11 @@ class Neo4jManager:
|
||||
|
||||
return {"nodes": nodes, "relationships": relationships}
|
||||
|
||||
|
||||
# 全局单例
|
||||
_neo4j_manager = None
|
||||
|
||||
|
||||
def get_neo4j_manager() -> Neo4jManager:
|
||||
"""获取 Neo4j 管理器单例"""
|
||||
global _neo4j_manager
|
||||
@@ -972,6 +980,7 @@ def get_neo4j_manager() -> Neo4jManager:
|
||||
_neo4j_manager = Neo4jManager()
|
||||
return _neo4j_manager
|
||||
|
||||
|
||||
def close_neo4j_manager() -> None:
|
||||
"""关闭 Neo4j 连接"""
|
||||
global _neo4j_manager
|
||||
@@ -979,6 +988,7 @@ def close_neo4j_manager() -> None:
|
||||
_neo4j_manager.close()
|
||||
_neo4j_manager = None
|
||||
|
||||
|
||||
# 便捷函数
|
||||
def sync_project_to_neo4j(
|
||||
project_id: str, project_name: str, entities: list[dict], relations: list[dict]
|
||||
@@ -1033,6 +1043,7 @@ def sync_project_to_neo4j(
|
||||
f"Synced project {project_id} to Neo4j: {len(entities)} entities, {len(relations)} relations"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试代码
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
@@ -29,6 +29,7 @@ import httpx
|
||||
# Database path
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
|
||||
|
||||
|
||||
class AlertSeverity(StrEnum):
|
||||
"""告警严重级别 P0-P3"""
|
||||
|
||||
@@ -37,6 +38,7 @@ class AlertSeverity(StrEnum):
|
||||
P2 = "p2" # 一般 - 部分功能受影响,需要4小时内处理
|
||||
P3 = "p3" # 轻微 - 非核心功能问题,24小时内处理
|
||||
|
||||
|
||||
class AlertStatus(StrEnum):
|
||||
"""告警状态"""
|
||||
|
||||
@@ -45,6 +47,7 @@ class AlertStatus(StrEnum):
|
||||
ACKNOWLEDGED = "acknowledged" # 已确认
|
||||
SUPPRESSED = "suppressed" # 已抑制
|
||||
|
||||
|
||||
class AlertChannelType(StrEnum):
|
||||
"""告警渠道类型"""
|
||||
|
||||
@@ -57,6 +60,7 @@ class AlertChannelType(StrEnum):
|
||||
SMS = "sms"
|
||||
WEBHOOK = "webhook"
|
||||
|
||||
|
||||
class AlertRuleType(StrEnum):
|
||||
"""告警规则类型"""
|
||||
|
||||
@@ -65,6 +69,7 @@ class AlertRuleType(StrEnum):
|
||||
PREDICTIVE = "predictive" # 预测性告警
|
||||
COMPOSITE = "composite" # 复合告警
|
||||
|
||||
|
||||
class ResourceType(StrEnum):
|
||||
"""资源类型"""
|
||||
|
||||
@@ -77,6 +82,7 @@ class ResourceType(StrEnum):
|
||||
CACHE = "cache"
|
||||
QUEUE = "queue"
|
||||
|
||||
|
||||
class ScalingAction(StrEnum):
|
||||
"""扩缩容动作"""
|
||||
|
||||
@@ -84,6 +90,7 @@ class ScalingAction(StrEnum):
|
||||
SCALE_DOWN = "scale_down" # 缩容
|
||||
MAINTAIN = "maintain" # 保持
|
||||
|
||||
|
||||
class HealthStatus(StrEnum):
|
||||
"""健康状态"""
|
||||
|
||||
@@ -92,6 +99,7 @@ class HealthStatus(StrEnum):
|
||||
UNHEALTHY = "unhealthy"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
class BackupStatus(StrEnum):
|
||||
"""备份状态"""
|
||||
|
||||
@@ -101,6 +109,7 @@ class BackupStatus(StrEnum):
|
||||
FAILED = "failed"
|
||||
VERIFIED = "verified"
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlertRule:
|
||||
"""告警规则"""
|
||||
@@ -124,6 +133,7 @@ class AlertRule:
|
||||
updated_at: str
|
||||
created_by: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlertChannel:
|
||||
"""告警渠道配置"""
|
||||
@@ -141,6 +151,7 @@ class AlertChannel:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Alert:
|
||||
"""告警实例"""
|
||||
@@ -164,6 +175,7 @@ class Alert:
|
||||
notification_sent: dict[str, bool] # 渠道发送状态
|
||||
suppression_count: int # 抑制计数
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlertSuppressionRule:
|
||||
"""告警抑制规则"""
|
||||
@@ -177,6 +189,7 @@ class AlertSuppressionRule:
|
||||
created_at: str
|
||||
expires_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlertGroup:
|
||||
"""告警聚合组"""
|
||||
@@ -188,6 +201,7 @@ class AlertGroup:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ResourceMetric:
|
||||
"""资源指标"""
|
||||
@@ -202,6 +216,7 @@ class ResourceMetric:
|
||||
timestamp: str
|
||||
metadata: dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class CapacityPlan:
|
||||
"""容量规划"""
|
||||
@@ -217,6 +232,7 @@ class CapacityPlan:
|
||||
estimated_cost: float
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class AutoScalingPolicy:
|
||||
"""自动扩缩容策略"""
|
||||
@@ -237,6 +253,7 @@ class AutoScalingPolicy:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScalingEvent:
|
||||
"""扩缩容事件"""
|
||||
@@ -254,6 +271,7 @@ class ScalingEvent:
|
||||
completed_at: str | None
|
||||
error_message: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class HealthCheck:
|
||||
"""健康检查配置"""
|
||||
@@ -274,6 +292,7 @@ class HealthCheck:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class HealthCheckResult:
|
||||
"""健康检查结果"""
|
||||
@@ -287,6 +306,7 @@ class HealthCheckResult:
|
||||
details: dict
|
||||
checked_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class FailoverConfig:
|
||||
"""故障转移配置"""
|
||||
@@ -304,6 +324,7 @@ class FailoverConfig:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class FailoverEvent:
|
||||
"""故障转移事件"""
|
||||
@@ -319,6 +340,7 @@ class FailoverEvent:
|
||||
completed_at: str | None
|
||||
rolled_back_at: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class BackupJob:
|
||||
"""备份任务"""
|
||||
@@ -338,6 +360,7 @@ class BackupJob:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class BackupRecord:
|
||||
"""备份记录"""
|
||||
@@ -354,6 +377,7 @@ class BackupRecord:
|
||||
error_message: str | None
|
||||
storage_path: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class CostReport:
|
||||
"""成本报告"""
|
||||
@@ -368,6 +392,7 @@ class CostReport:
|
||||
anomalies: list[dict] # 异常检测
|
||||
created_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ResourceUtilization:
|
||||
"""资源利用率"""
|
||||
@@ -383,6 +408,7 @@ class ResourceUtilization:
|
||||
report_date: str
|
||||
recommendations: list[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class IdleResource:
|
||||
"""闲置资源"""
|
||||
@@ -399,6 +425,7 @@ class IdleResource:
|
||||
recommendation: str
|
||||
detected_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class CostOptimizationSuggestion:
|
||||
"""成本优化建议"""
|
||||
@@ -418,6 +445,7 @@ class CostOptimizationSuggestion:
|
||||
created_at: str
|
||||
applied_at: str | None
|
||||
|
||||
|
||||
class OpsManager:
|
||||
"""运维与监控管理主类"""
|
||||
|
||||
@@ -3065,9 +3093,11 @@ class OpsManager:
|
||||
applied_at=row["applied_at"],
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_ops_manager = None
|
||||
|
||||
|
||||
def get_ops_manager() -> OpsManager:
|
||||
global _ops_manager
|
||||
if _ops_manager is None:
|
||||
|
||||
@@ -9,6 +9,7 @@ from datetime import datetime
|
||||
|
||||
import oss2
|
||||
|
||||
|
||||
class OSSUploader:
|
||||
def __init__(self):
|
||||
self.access_key = os.getenv("ALI_ACCESS_KEY")
|
||||
@@ -40,9 +41,11 @@ class OSSUploader:
|
||||
"""删除 OSS 对象"""
|
||||
self.bucket.delete_object(object_name)
|
||||
|
||||
|
||||
# 单例
|
||||
_oss_uploader = None
|
||||
|
||||
|
||||
def get_oss_uploader() -> OSSUploader:
|
||||
global _oss_uploader
|
||||
if _oss_uploader is None:
|
||||
|
||||
@@ -42,6 +42,7 @@ except ImportError:
|
||||
|
||||
# ==================== 数据模型 ====================
|
||||
|
||||
|
||||
@dataclass
|
||||
class CacheStats:
|
||||
"""缓存统计数据模型"""
|
||||
@@ -58,6 +59,7 @@ class CacheStats:
|
||||
if self.total_requests > 0:
|
||||
self.hit_rate = round(self.hits / self.total_requests, 4)
|
||||
|
||||
|
||||
@dataclass
|
||||
class CacheEntry:
|
||||
"""缓存条目数据模型"""
|
||||
@@ -70,6 +72,7 @@ class CacheEntry:
|
||||
last_accessed: float = 0
|
||||
size_bytes: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class PerformanceMetric:
|
||||
"""性能指标数据模型"""
|
||||
@@ -91,6 +94,7 @@ class PerformanceMetric:
|
||||
"metadata": self.metadata,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class TaskInfo:
|
||||
"""任务信息数据模型"""
|
||||
@@ -122,6 +126,7 @@ class TaskInfo:
|
||||
"max_retries": self.max_retries,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ShardInfo:
|
||||
"""分片信息数据模型"""
|
||||
@@ -134,8 +139,10 @@ class ShardInfo:
|
||||
created_at: str = ""
|
||||
last_accessed: str = ""
|
||||
|
||||
|
||||
# ==================== Redis 缓存层 ====================
|
||||
|
||||
|
||||
class CacheManager:
|
||||
"""
|
||||
缓存管理器
|
||||
@@ -592,8 +599,10 @@ class CacheManager:
|
||||
|
||||
return count
|
||||
|
||||
|
||||
# ==================== 数据库分片 ====================
|
||||
|
||||
|
||||
class DatabaseSharding:
|
||||
"""
|
||||
数据库分片管理器
|
||||
@@ -893,8 +902,10 @@ class DatabaseSharding:
|
||||
"message": "Rebalancing analysis completed",
|
||||
}
|
||||
|
||||
|
||||
# ==================== 异步任务队列 ====================
|
||||
|
||||
|
||||
class TaskQueue:
|
||||
"""
|
||||
异步任务队列管理器
|
||||
@@ -1276,8 +1287,10 @@ class TaskQueue:
|
||||
"backend": "celery" if self.use_celery else "memory",
|
||||
}
|
||||
|
||||
|
||||
# ==================== 性能监控 ====================
|
||||
|
||||
|
||||
class PerformanceMonitor:
|
||||
"""
|
||||
性能监控器
|
||||
@@ -1594,8 +1607,10 @@ class PerformanceMonitor:
|
||||
|
||||
return deleted
|
||||
|
||||
|
||||
# ==================== 性能装饰器 ====================
|
||||
|
||||
|
||||
def cached(
|
||||
cache_manager: CacheManager,
|
||||
key_prefix: str = "",
|
||||
@@ -1640,6 +1655,7 @@ def cached(
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | None = None) -> None:
|
||||
"""
|
||||
性能监控装饰器
|
||||
@@ -1667,8 +1683,10 @@ def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | Non
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
# ==================== 性能管理器 ====================
|
||||
|
||||
|
||||
class PerformanceManager:
|
||||
"""
|
||||
性能管理器 - 统一入口
|
||||
@@ -1730,9 +1748,11 @@ class PerformanceManager:
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
# 单例模式
|
||||
_performance_manager = None
|
||||
|
||||
|
||||
def get_performance_manager(
|
||||
db_path: str = "insightflow.db", redis_url: str | None = None, enable_sharding: bool = False
|
||||
) -> PerformanceManager:
|
||||
|
||||
@@ -28,6 +28,7 @@ try:
|
||||
except ImportError:
|
||||
WEBDAV_AVAILABLE = False
|
||||
|
||||
|
||||
class PluginType(Enum):
|
||||
"""插件类型"""
|
||||
|
||||
@@ -39,6 +40,7 @@ class PluginType(Enum):
|
||||
WEBDAV = "webdav"
|
||||
CUSTOM = "custom"
|
||||
|
||||
|
||||
class PluginStatus(Enum):
|
||||
"""插件状态"""
|
||||
|
||||
@@ -47,6 +49,7 @@ class PluginStatus(Enum):
|
||||
ERROR = "error"
|
||||
PENDING = "pending"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Plugin:
|
||||
"""插件配置"""
|
||||
@@ -62,6 +65,7 @@ class Plugin:
|
||||
last_used_at: str | None = None
|
||||
use_count: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class PluginConfig:
|
||||
"""插件详细配置"""
|
||||
@@ -74,6 +78,7 @@ class PluginConfig:
|
||||
created_at: str = ""
|
||||
updated_at: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class BotSession:
|
||||
"""机器人会话"""
|
||||
@@ -91,6 +96,7 @@ class BotSession:
|
||||
last_message_at: str | None = None
|
||||
message_count: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookEndpoint:
|
||||
"""Webhook 端点配置(Zapier/Make集成)"""
|
||||
@@ -109,6 +115,7 @@ class WebhookEndpoint:
|
||||
last_triggered_at: str | None = None
|
||||
trigger_count: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebDAVSync:
|
||||
"""WebDAV 同步配置"""
|
||||
@@ -130,6 +137,7 @@ class WebDAVSync:
|
||||
updated_at: str = ""
|
||||
sync_count: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChromeExtensionToken:
|
||||
"""Chrome 扩展令牌"""
|
||||
@@ -146,6 +154,7 @@ class ChromeExtensionToken:
|
||||
use_count: int = 0
|
||||
is_revoked: bool = False
|
||||
|
||||
|
||||
class PluginManager:
|
||||
"""插件管理主类"""
|
||||
|
||||
@@ -385,6 +394,7 @@ class PluginManager:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
class ChromeExtensionHandler:
|
||||
"""Chrome 扩展处理器"""
|
||||
|
||||
@@ -588,6 +598,7 @@ class ChromeExtensionHandler:
|
||||
"content_length": len(content),
|
||||
}
|
||||
|
||||
|
||||
class BotHandler:
|
||||
"""飞书/钉钉机器人处理器"""
|
||||
|
||||
@@ -915,6 +926,7 @@ class BotHandler:
|
||||
)
|
||||
return response.status_code == 200
|
||||
|
||||
|
||||
class WebhookIntegration:
|
||||
"""Zapier/Make Webhook 集成"""
|
||||
|
||||
@@ -1137,6 +1149,7 @@ class WebhookIntegration:
|
||||
"message": "Test event sent successfully" if success else "Failed to send test event",
|
||||
}
|
||||
|
||||
|
||||
class WebDAVSyncManager:
|
||||
"""WebDAV 同步管理"""
|
||||
|
||||
@@ -1397,9 +1410,11 @@ class WebDAVSyncManager:
|
||||
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_plugin_manager = None
|
||||
|
||||
|
||||
def get_plugin_manager(db_manager=None) -> None:
|
||||
"""获取 PluginManager 单例"""
|
||||
global _plugin_manager
|
||||
|
||||
@@ -12,6 +12,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from functools import wraps
|
||||
|
||||
|
||||
@dataclass
|
||||
class RateLimitConfig:
|
||||
"""限流配置"""
|
||||
@@ -20,6 +21,7 @@ class RateLimitConfig:
|
||||
burst_size: int = 10 # 突发请求数
|
||||
window_size: int = 60 # 窗口大小(秒)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RateLimitInfo:
|
||||
"""限流信息"""
|
||||
@@ -29,6 +31,7 @@ class RateLimitInfo:
|
||||
reset_time: int # 重置时间戳
|
||||
retry_after: int # 需要等待的秒数
|
||||
|
||||
|
||||
class SlidingWindowCounter:
|
||||
"""滑动窗口计数器"""
|
||||
|
||||
@@ -60,6 +63,7 @@ class SlidingWindowCounter:
|
||||
for k in old_keys:
|
||||
self.requests.pop(k, None)
|
||||
|
||||
|
||||
class RateLimiter:
|
||||
"""API 限流器"""
|
||||
|
||||
@@ -155,9 +159,11 @@ class RateLimiter:
|
||||
self.counters.clear()
|
||||
self.configs.clear()
|
||||
|
||||
|
||||
# 全局限流器实例
|
||||
_rate_limiter: RateLimiter | None = None
|
||||
|
||||
|
||||
def get_rate_limiter() -> RateLimiter:
|
||||
"""获取限流器实例"""
|
||||
global _rate_limiter
|
||||
@@ -165,6 +171,7 @@ def get_rate_limiter() -> RateLimiter:
|
||||
_rate_limiter = RateLimiter()
|
||||
return _rate_limiter
|
||||
|
||||
|
||||
# 限流装饰器(用于函数级别限流)
|
||||
def rate_limit(requests_per_minute: int = 60, key_func: Callable | None = None) -> None:
|
||||
"""
|
||||
@@ -208,5 +215,6 @@ def rate_limit(requests_per_minute: int = 60, key_func: Callable | None = None)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class RateLimitExceeded(Exception):
|
||||
"""限流异常"""
|
||||
|
||||
@@ -19,6 +19,7 @@ from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class SearchOperator(Enum):
|
||||
"""搜索操作符"""
|
||||
|
||||
@@ -26,6 +27,7 @@ class SearchOperator(Enum):
|
||||
OR = "OR"
|
||||
NOT = "NOT"
|
||||
|
||||
|
||||
# 尝试导入 sentence-transformers 用于语义搜索
|
||||
try:
|
||||
from sentence_transformers import SentenceTransformer
|
||||
@@ -37,6 +39,7 @@ except ImportError:
|
||||
|
||||
# ==================== 数据模型 ====================
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchResult:
|
||||
"""搜索结果数据模型"""
|
||||
@@ -60,6 +63,7 @@ class SearchResult:
|
||||
"metadata": self.metadata,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SemanticSearchResult:
|
||||
"""语义搜索结果数据模型"""
|
||||
@@ -85,6 +89,7 @@ class SemanticSearchResult:
|
||||
result["embedding_dim"] = len(self.embedding)
|
||||
return result
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityPath:
|
||||
"""实体关系路径数据模型"""
|
||||
@@ -114,6 +119,7 @@ class EntityPath:
|
||||
"path_description": self.path_description,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class KnowledgeGap:
|
||||
"""知识缺口数据模型"""
|
||||
@@ -141,6 +147,7 @@ class KnowledgeGap:
|
||||
"metadata": self.metadata,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchIndex:
|
||||
"""搜索索引数据模型"""
|
||||
@@ -154,6 +161,7 @@ class SearchIndex:
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class TextEmbedding:
|
||||
"""文本 Embedding 数据模型"""
|
||||
@@ -166,8 +174,10 @@ class TextEmbedding:
|
||||
model_name: str
|
||||
created_at: str
|
||||
|
||||
|
||||
# ==================== 全文搜索 ====================
|
||||
|
||||
|
||||
class FullTextSearch:
|
||||
"""
|
||||
全文搜索模块
|
||||
@@ -776,8 +786,10 @@ class FullTextSearch:
|
||||
conn.close()
|
||||
return stats
|
||||
|
||||
|
||||
# ==================== 语义搜索 ====================
|
||||
|
||||
|
||||
class SemanticSearch:
|
||||
"""
|
||||
语义搜索模块
|
||||
@@ -1138,8 +1150,10 @@ class SemanticSearch:
|
||||
print(f"删除 embedding 失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
# ==================== 实体关系路径发现 ====================
|
||||
|
||||
|
||||
class EntityPathDiscovery:
|
||||
"""
|
||||
实体关系路径发现模块
|
||||
@@ -1609,8 +1623,10 @@ class EntityPathDiscovery:
|
||||
bridge_scores.sort(key=lambda x: x["bridge_score"], reverse=True)
|
||||
return bridge_scores[:20] # 返回前20
|
||||
|
||||
|
||||
# ==================== 知识缺口识别 ====================
|
||||
|
||||
|
||||
class KnowledgeGapDetection:
|
||||
"""
|
||||
知识缺口识别模块
|
||||
@@ -2013,8 +2029,10 @@ class KnowledgeGapDetection:
|
||||
|
||||
return recommendations
|
||||
|
||||
|
||||
# ==================== 搜索管理器 ====================
|
||||
|
||||
|
||||
class SearchManager:
|
||||
"""
|
||||
搜索管理器 - 统一入口
|
||||
@@ -2187,9 +2205,11 @@ class SearchManager:
|
||||
"semantic_search_available": self.semantic_search.is_available(),
|
||||
}
|
||||
|
||||
|
||||
# 单例模式
|
||||
_search_manager = None
|
||||
|
||||
|
||||
def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
|
||||
"""获取搜索管理器单例"""
|
||||
global _search_manager
|
||||
@@ -2197,6 +2217,7 @@ def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
|
||||
_search_manager = SearchManager(db_path)
|
||||
return _search_manager
|
||||
|
||||
|
||||
# 便捷函数
|
||||
def fulltext_search(
|
||||
query: str, project_id: str | None = None, limit: int = 20
|
||||
@@ -2205,6 +2226,7 @@ def fulltext_search(
|
||||
manager = get_search_manager()
|
||||
return manager.fulltext_search.search(query, project_id, limit=limit)
|
||||
|
||||
|
||||
def semantic_search(
|
||||
query: str, project_id: str | None = None, top_k: int = 10
|
||||
) -> list[SemanticSearchResult]:
|
||||
@@ -2212,11 +2234,13 @@ def semantic_search(
|
||||
manager = get_search_manager()
|
||||
return manager.semantic_search.search(query, project_id, top_k=top_k)
|
||||
|
||||
|
||||
def find_entity_path(source_id: str, target_id: str, max_depth: int = 5) -> EntityPath | None:
|
||||
"""查找实体路径便捷函数"""
|
||||
manager = get_search_manager()
|
||||
return manager.path_discovery.find_shortest_path(source_id, target_id, max_depth)
|
||||
|
||||
|
||||
def detect_knowledge_gaps(project_id: str) -> list[KnowledgeGap]:
|
||||
"""知识缺口检测便捷函数"""
|
||||
manager = get_search_manager()
|
||||
|
||||
@@ -25,6 +25,7 @@ except ImportError:
|
||||
CRYPTO_AVAILABLE = False
|
||||
print("Warning: cryptography not available, encryption features disabled")
|
||||
|
||||
|
||||
class AuditActionType(Enum):
|
||||
"""审计动作类型"""
|
||||
|
||||
@@ -47,6 +48,7 @@ class AuditActionType(Enum):
|
||||
WEBHOOK_SEND = "webhook_send"
|
||||
BOT_MESSAGE = "bot_message"
|
||||
|
||||
|
||||
class DataSensitivityLevel(Enum):
|
||||
"""数据敏感度级别"""
|
||||
|
||||
@@ -55,6 +57,7 @@ class DataSensitivityLevel(Enum):
|
||||
CONFIDENTIAL = "confidential" # 机密
|
||||
SECRET = "secret" # 绝密
|
||||
|
||||
|
||||
class MaskingRuleType(Enum):
|
||||
"""脱敏规则类型"""
|
||||
|
||||
@@ -66,6 +69,7 @@ class MaskingRuleType(Enum):
|
||||
ADDRESS = "address" # 地址
|
||||
CUSTOM = "custom" # 自定义
|
||||
|
||||
|
||||
@dataclass
|
||||
class AuditLog:
|
||||
"""审计日志条目"""
|
||||
@@ -87,6 +91,7 @@ class AuditLog:
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class EncryptionConfig:
|
||||
"""加密配置"""
|
||||
@@ -104,6 +109,7 @@ class EncryptionConfig:
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MaskingRule:
|
||||
"""脱敏规则"""
|
||||
@@ -123,6 +129,7 @@ class MaskingRule:
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class DataAccessPolicy:
|
||||
"""数据访问策略"""
|
||||
@@ -144,6 +151,7 @@ class DataAccessPolicy:
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccessRequest:
|
||||
"""访问请求(用于需要审批的访问)"""
|
||||
@@ -161,6 +169,7 @@ class AccessRequest:
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
||||
class SecurityManager:
|
||||
"""安全管理器"""
|
||||
|
||||
@@ -1229,9 +1238,11 @@ class SecurityManager:
|
||||
created_at=row[8],
|
||||
)
|
||||
|
||||
|
||||
# 全局安全管理器实例
|
||||
_security_manager = None
|
||||
|
||||
|
||||
def get_security_manager(db_path: str = "insightflow.db") -> SecurityManager:
|
||||
"""获取安全管理器实例"""
|
||||
global _security_manager
|
||||
|
||||
@@ -21,6 +21,7 @@ from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SubscriptionStatus(StrEnum):
|
||||
"""订阅状态"""
|
||||
|
||||
@@ -31,6 +32,7 @@ class SubscriptionStatus(StrEnum):
|
||||
TRIAL = "trial" # 试用中
|
||||
PENDING = "pending" # 待支付
|
||||
|
||||
|
||||
class PaymentProvider(StrEnum):
|
||||
"""支付提供商"""
|
||||
|
||||
@@ -39,6 +41,7 @@ class PaymentProvider(StrEnum):
|
||||
WECHAT = "wechat" # 微信支付
|
||||
BANK_TRANSFER = "bank_transfer" # 银行转账
|
||||
|
||||
|
||||
class PaymentStatus(StrEnum):
|
||||
"""支付状态"""
|
||||
|
||||
@@ -49,6 +52,7 @@ class PaymentStatus(StrEnum):
|
||||
REFUNDED = "refunded" # 已退款
|
||||
PARTIAL_REFUNDED = "partial_refunded" # 部分退款
|
||||
|
||||
|
||||
class InvoiceStatus(StrEnum):
|
||||
"""发票状态"""
|
||||
|
||||
@@ -59,6 +63,7 @@ class InvoiceStatus(StrEnum):
|
||||
VOID = "void" # 作废
|
||||
CREDIT_NOTE = "credit_note" # 贷项通知单
|
||||
|
||||
|
||||
class RefundStatus(StrEnum):
|
||||
"""退款状态"""
|
||||
|
||||
@@ -68,6 +73,7 @@ class RefundStatus(StrEnum):
|
||||
COMPLETED = "completed" # 已完成
|
||||
FAILED = "failed" # 失败
|
||||
|
||||
|
||||
@dataclass
|
||||
class SubscriptionPlan:
|
||||
"""订阅计划数据类"""
|
||||
@@ -86,6 +92,7 @@ class SubscriptionPlan:
|
||||
updated_at: datetime
|
||||
metadata: dict[str, Any]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Subscription:
|
||||
"""订阅数据类"""
|
||||
@@ -106,6 +113,7 @@ class Subscription:
|
||||
updated_at: datetime
|
||||
metadata: dict[str, Any]
|
||||
|
||||
|
||||
@dataclass
|
||||
class UsageRecord:
|
||||
"""用量记录数据类"""
|
||||
@@ -120,6 +128,7 @@ class UsageRecord:
|
||||
description: str | None
|
||||
metadata: dict[str, Any]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Payment:
|
||||
"""支付记录数据类"""
|
||||
@@ -141,6 +150,7 @@ class Payment:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Invoice:
|
||||
"""发票数据类"""
|
||||
@@ -164,6 +174,7 @@ class Invoice:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Refund:
|
||||
"""退款数据类"""
|
||||
@@ -186,6 +197,7 @@ class Refund:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class BillingHistory:
|
||||
"""账单历史数据类"""
|
||||
@@ -201,6 +213,7 @@ class BillingHistory:
|
||||
created_at: datetime
|
||||
metadata: dict[str, Any]
|
||||
|
||||
|
||||
class SubscriptionManager:
|
||||
"""订阅与计费管理器"""
|
||||
|
||||
@@ -2187,9 +2200,11 @@ class SubscriptionManager:
|
||||
metadata=json.loads(row["metadata"] or "{}"),
|
||||
)
|
||||
|
||||
|
||||
# 全局订阅管理器实例
|
||||
subscription_manager = None
|
||||
|
||||
|
||||
def get_subscription_manager(db_path: str = "insightflow.db") -> SubscriptionManager:
|
||||
"""获取订阅管理器实例(单例模式)"""
|
||||
global subscription_manager
|
||||
|
||||
@@ -23,6 +23,7 @@ from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TenantLimits:
|
||||
"""租户资源限制常量"""
|
||||
|
||||
@@ -42,6 +43,7 @@ class TenantLimits:
|
||||
|
||||
UNLIMITED = -1
|
||||
|
||||
|
||||
class TenantStatus(StrEnum):
|
||||
"""租户状态"""
|
||||
|
||||
@@ -51,6 +53,7 @@ class TenantStatus(StrEnum):
|
||||
EXPIRED = "expired" # 过期
|
||||
PENDING = "pending" # 待激活
|
||||
|
||||
|
||||
class TenantTier(StrEnum):
|
||||
"""租户订阅层级"""
|
||||
|
||||
@@ -58,6 +61,7 @@ class TenantTier(StrEnum):
|
||||
PRO = "pro" # 专业版
|
||||
ENTERPRISE = "enterprise" # 企业版
|
||||
|
||||
|
||||
class TenantRole(StrEnum):
|
||||
"""租户角色"""
|
||||
|
||||
@@ -66,6 +70,7 @@ class TenantRole(StrEnum):
|
||||
MEMBER = "member" # 成员
|
||||
VIEWER = "viewer" # 查看者
|
||||
|
||||
|
||||
class DomainStatus(StrEnum):
|
||||
"""域名状态"""
|
||||
|
||||
@@ -74,6 +79,7 @@ class DomainStatus(StrEnum):
|
||||
FAILED = "failed" # 验证失败
|
||||
EXPIRED = "expired" # 已过期
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tenant:
|
||||
"""租户数据类"""
|
||||
@@ -92,6 +98,7 @@ class Tenant:
|
||||
resource_limits: dict[str, Any] # 资源限制
|
||||
metadata: dict[str, Any] # 元数据
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantDomain:
|
||||
"""租户域名数据类"""
|
||||
@@ -109,6 +116,7 @@ class TenantDomain:
|
||||
ssl_enabled: bool # SSL 是否启用
|
||||
ssl_expires_at: datetime | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantBranding:
|
||||
"""租户品牌配置数据类"""
|
||||
@@ -126,6 +134,7 @@ class TenantBranding:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantMember:
|
||||
"""租户成员数据类"""
|
||||
@@ -142,6 +151,7 @@ class TenantMember:
|
||||
last_active_at: datetime | None
|
||||
status: str # active/pending/suspended
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantPermission:
|
||||
"""租户权限定义数据类"""
|
||||
@@ -156,6 +166,7 @@ class TenantPermission:
|
||||
conditions: dict | None # 条件限制
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class TenantManager:
|
||||
"""租户管理器 - 多租户 SaaS 架构核心"""
|
||||
|
||||
@@ -1599,8 +1610,10 @@ class TenantManager:
|
||||
status=row["status"],
|
||||
)
|
||||
|
||||
|
||||
# ==================== 租户上下文管理 ====================
|
||||
|
||||
|
||||
class TenantContext:
|
||||
"""租户上下文管理器 - 用于请求级别的租户隔离"""
|
||||
|
||||
@@ -1633,9 +1646,11 @@ class TenantContext:
|
||||
cls._current_tenant_id = None
|
||||
cls._current_user_id = None
|
||||
|
||||
|
||||
# 全局租户管理器实例
|
||||
tenant_manager = None
|
||||
|
||||
|
||||
def get_tenant_manager(db_path: str = "insightflow.db") -> TenantManager:
|
||||
"""获取租户管理器实例(单例模式)"""
|
||||
global tenant_manager
|
||||
|
||||
@@ -20,6 +20,7 @@ from search_manager import (
|
||||
# 添加 backend 到路径
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def test_fulltext_search():
|
||||
"""测试全文搜索"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -62,6 +63,7 @@ def test_fulltext_search():
|
||||
print("\n✓ 全文搜索测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_semantic_search():
|
||||
"""测试语义搜索"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -97,6 +99,7 @@ def test_semantic_search():
|
||||
print("\n✓ 语义搜索测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_entity_path_discovery():
|
||||
"""测试实体路径发现"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -115,6 +118,7 @@ def test_entity_path_discovery():
|
||||
print("\n✓ 实体路径发现测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_knowledge_gap_detection():
|
||||
"""测试知识缺口识别"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -133,6 +137,7 @@ def test_knowledge_gap_detection():
|
||||
print("\n✓ 知识缺口识别测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_cache_manager():
|
||||
"""测试缓存管理器"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -180,6 +185,7 @@ def test_cache_manager():
|
||||
print("\n✓ 缓存管理器测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_task_queue():
|
||||
"""测试任务队列"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -220,6 +226,7 @@ def test_task_queue():
|
||||
print("\n✓ 任务队列测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_performance_monitor():
|
||||
"""测试性能监控"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -266,6 +273,7 @@ def test_performance_monitor():
|
||||
print("\n✓ 性能监控测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_search_manager():
|
||||
"""测试搜索管理器"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -286,6 +294,7 @@ def test_search_manager():
|
||||
print("\n✓ 搜索管理器测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def test_performance_manager():
|
||||
"""测试性能管理器"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -310,6 +319,7 @@ def test_performance_manager():
|
||||
print("\n✓ 性能管理器测试完成")
|
||||
return True
|
||||
|
||||
|
||||
def run_all_tests():
|
||||
"""运行所有测试"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -396,6 +406,7 @@ def run_all_tests():
|
||||
|
||||
return passed == total
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = run_all_tests()
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
@@ -17,6 +17,7 @@ from tenant_manager import get_tenant_manager
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def test_tenant_management():
|
||||
"""测试租户管理功能"""
|
||||
print("=" * 60)
|
||||
@@ -64,6 +65,7 @@ def test_tenant_management():
|
||||
|
||||
return tenant.id
|
||||
|
||||
|
||||
def test_domain_management(tenant_id: str):
|
||||
"""测试域名管理功能"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -109,6 +111,7 @@ def test_domain_management(tenant_id: str):
|
||||
|
||||
return domain.id
|
||||
|
||||
|
||||
def test_branding_management(tenant_id: str):
|
||||
"""测试品牌白标功能"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -148,6 +151,7 @@ def test_branding_management(tenant_id: str):
|
||||
|
||||
return branding.id
|
||||
|
||||
|
||||
def test_member_management(tenant_id: str):
|
||||
"""测试成员管理功能"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -202,6 +206,7 @@ def test_member_management(tenant_id: str):
|
||||
|
||||
return member1.id, member2.id
|
||||
|
||||
|
||||
def test_usage_tracking(tenant_id: str):
|
||||
"""测试资源使用统计功能"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -243,6 +248,7 @@ def test_usage_tracking(tenant_id: str):
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def cleanup(tenant_id: str, domain_id: str, member_ids: list):
|
||||
"""清理测试数据"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -266,6 +272,7 @@ def cleanup(tenant_id: str, domain_id: str, member_ids: list):
|
||||
manager.delete_tenant(tenant_id)
|
||||
print(f"✅ 租户已删除: {tenant_id}")
|
||||
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("\n" + "=" * 60)
|
||||
@@ -303,5 +310,6 @@ def main():
|
||||
except Exception as e:
|
||||
print(f"⚠️ 清理失败: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -11,6 +11,7 @@ from subscription_manager import PaymentProvider, SubscriptionManager
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def test_subscription_manager():
|
||||
"""测试订阅管理器"""
|
||||
print("=" * 60)
|
||||
@@ -223,6 +224,7 @@ def test_subscription_manager():
|
||||
os.remove(db_path)
|
||||
print(f"\n清理临时数据库: {db_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
test_subscription_manager()
|
||||
|
||||
@@ -13,6 +13,7 @@ from ai_manager import ModelType, PredictionType, get_ai_manager
|
||||
# Add backend directory to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def test_custom_model():
|
||||
"""测试自定义模型功能"""
|
||||
print("\n=== 测试自定义模型 ===")
|
||||
@@ -87,6 +88,7 @@ def test_custom_model():
|
||||
|
||||
return model.id
|
||||
|
||||
|
||||
async def test_train_and_predict(model_id: str):
|
||||
"""测试训练和预测"""
|
||||
print("\n=== 测试模型训练和预测 ===")
|
||||
@@ -113,6 +115,7 @@ async def test_train_and_predict(model_id: str):
|
||||
except Exception as e:
|
||||
print(f" 预测失败: {e}")
|
||||
|
||||
|
||||
def test_prediction_models():
|
||||
"""测试预测模型"""
|
||||
print("\n=== 测试预测模型 ===")
|
||||
@@ -154,6 +157,7 @@ def test_prediction_models():
|
||||
|
||||
return trend_model.id, anomaly_model.id
|
||||
|
||||
|
||||
async def test_predictions(trend_model_id: str, anomaly_model_id: str):
|
||||
"""测试预测功能"""
|
||||
print("\n=== 测试预测功能 ===")
|
||||
@@ -188,6 +192,7 @@ async def test_predictions(trend_model_id: str, anomaly_model_id: str):
|
||||
)
|
||||
print(f" 检测结果: {anomaly_result.prediction_data}")
|
||||
|
||||
|
||||
def test_kg_rag():
|
||||
"""测试知识图谱 RAG"""
|
||||
print("\n=== 测试知识图谱 RAG ===")
|
||||
@@ -217,6 +222,7 @@ def test_kg_rag():
|
||||
|
||||
return rag.id
|
||||
|
||||
|
||||
async def test_kg_rag_query(rag_id: str):
|
||||
"""测试 RAG 查询"""
|
||||
print("\n=== 测试知识图谱 RAG 查询 ===")
|
||||
@@ -287,6 +293,7 @@ async def test_kg_rag_query(rag_id: str):
|
||||
except Exception as e:
|
||||
print(f" 查询失败: {e}")
|
||||
|
||||
|
||||
async def test_smart_summary():
|
||||
"""测试智能摘要"""
|
||||
print("\n=== 测试智能摘要 ===")
|
||||
@@ -334,6 +341,7 @@ async def test_smart_summary():
|
||||
except Exception as e:
|
||||
print(f" 生成失败: {e}")
|
||||
|
||||
|
||||
async def main():
|
||||
"""主测试函数"""
|
||||
print("=" * 60)
|
||||
@@ -372,5 +380,6 @@ async def main():
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -32,6 +32,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
if backend_dir not in sys.path:
|
||||
sys.path.insert(0, backend_dir)
|
||||
|
||||
|
||||
class TestGrowthManager:
|
||||
"""测试 Growth Manager 功能"""
|
||||
|
||||
@@ -734,10 +735,12 @@ class TestGrowthManager:
|
||||
print("✨ 测试完成!")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
async def main():
|
||||
"""主函数"""
|
||||
tester = TestGrowthManager()
|
||||
await tester.run_all_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -29,6 +29,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
if backend_dir not in sys.path:
|
||||
sys.path.insert(0, backend_dir)
|
||||
|
||||
|
||||
class TestDeveloperEcosystem:
|
||||
"""开发者生态系统测试类"""
|
||||
|
||||
@@ -687,10 +688,12 @@ console.log('Upload complete:', result.id);
|
||||
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
test = TestDeveloperEcosystem()
|
||||
test.run_all_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -30,6 +30,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
if backend_dir not in sys.path:
|
||||
sys.path.insert(0, backend_dir)
|
||||
|
||||
|
||||
class TestOpsManager:
|
||||
"""测试运维与监控管理器"""
|
||||
|
||||
@@ -721,10 +722,12 @@ class TestOpsManager:
|
||||
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
test = TestOpsManager()
|
||||
test.run_all_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -8,6 +8,7 @@ import time
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
|
||||
class TingwuClient:
|
||||
def __init__(self):
|
||||
self.access_key = os.getenv("ALI_ACCESS_KEY", "")
|
||||
|
||||
@@ -33,6 +33,7 @@ from apscheduler.triggers.interval import IntervalTrigger
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WorkflowStatus(Enum):
|
||||
"""工作流状态"""
|
||||
|
||||
@@ -41,6 +42,7 @@ class WorkflowStatus(Enum):
|
||||
ERROR = "error"
|
||||
COMPLETED = "completed"
|
||||
|
||||
|
||||
class WorkflowType(Enum):
|
||||
"""工作流类型"""
|
||||
|
||||
@@ -50,6 +52,7 @@ class WorkflowType(Enum):
|
||||
SCHEDULED_REPORT = "scheduled_report" # 定时报告
|
||||
CUSTOM = "custom" # 自定义工作流
|
||||
|
||||
|
||||
class WebhookType(Enum):
|
||||
"""Webhook 类型"""
|
||||
|
||||
@@ -58,6 +61,7 @@ class WebhookType(Enum):
|
||||
SLACK = "slack"
|
||||
CUSTOM = "custom"
|
||||
|
||||
|
||||
class TaskStatus(Enum):
|
||||
"""任务执行状态"""
|
||||
|
||||
@@ -67,6 +71,7 @@ class TaskStatus(Enum):
|
||||
FAILED = "failed"
|
||||
CANCELLED = "cancelled"
|
||||
|
||||
|
||||
@dataclass
|
||||
class WorkflowTask:
|
||||
"""工作流任务定义"""
|
||||
@@ -90,6 +95,7 @@ class WorkflowTask:
|
||||
if not self.updated_at:
|
||||
self.updated_at = self.created_at
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookConfig:
|
||||
"""Webhook 配置"""
|
||||
@@ -114,6 +120,7 @@ class WebhookConfig:
|
||||
if not self.updated_at:
|
||||
self.updated_at = self.created_at
|
||||
|
||||
|
||||
@dataclass
|
||||
class Workflow:
|
||||
"""工作流定义"""
|
||||
@@ -143,6 +150,7 @@ class Workflow:
|
||||
if not self.updated_at:
|
||||
self.updated_at = self.created_at
|
||||
|
||||
|
||||
@dataclass
|
||||
class WorkflowLog:
|
||||
"""工作流执行日志"""
|
||||
@@ -163,6 +171,7 @@ class WorkflowLog:
|
||||
if not self.created_at:
|
||||
self.created_at = datetime.now().isoformat()
|
||||
|
||||
|
||||
class WebhookNotifier:
|
||||
"""Webhook 通知器 - 支持飞书、钉钉、Slack"""
|
||||
|
||||
@@ -318,6 +327,7 @@ class WebhookNotifier:
|
||||
"""关闭 HTTP 客户端"""
|
||||
await self.http_client.aclose()
|
||||
|
||||
|
||||
class WorkflowManager:
|
||||
"""工作流管理器 - 核心管理类"""
|
||||
|
||||
@@ -1488,9 +1498,11 @@ class WorkflowManager:
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# Singleton instance
|
||||
_workflow_manager = None
|
||||
|
||||
|
||||
def get_workflow_manager(db_manager=None) -> WorkflowManager:
|
||||
"""获取 WorkflowManager 单例"""
|
||||
global _workflow_manager
|
||||
|
||||
Reference in New Issue
Block a user