fix: auto-fix code issues (cron)

- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题 (E302, E305, E501)
- 修复行长度超过100字符的问题
- 修复F821未定义名称错误
This commit is contained in:
AutoFix Bot
2026-03-01 18:19:06 +08:00
parent 8f59c7b17c
commit e46c938b40
36 changed files with 1102 additions and 28 deletions

View File

@@ -27,6 +27,7 @@ import httpx
# Database path # Database path
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db") DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
class ModelType(StrEnum): class ModelType(StrEnum):
"""模型类型""" """模型类型"""
@@ -35,6 +36,7 @@ class ModelType(StrEnum):
SUMMARIZATION = "summarization" # 摘要 SUMMARIZATION = "summarization" # 摘要
PREDICTION = "prediction" # 预测 PREDICTION = "prediction" # 预测
class ModelStatus(StrEnum): class ModelStatus(StrEnum):
"""模型状态""" """模型状态"""
@@ -44,6 +46,7 @@ class ModelStatus(StrEnum):
FAILED = "failed" FAILED = "failed"
ARCHIVED = "archived" ARCHIVED = "archived"
class MultimodalProvider(StrEnum): class MultimodalProvider(StrEnum):
"""多模态模型提供商""" """多模态模型提供商"""
@@ -52,6 +55,7 @@ class MultimodalProvider(StrEnum):
GEMINI = "gemini-pro-vision" GEMINI = "gemini-pro-vision"
KIMI_VL = "kimi-vl" KIMI_VL = "kimi-vl"
class PredictionType(StrEnum): class PredictionType(StrEnum):
"""预测类型""" """预测类型"""
@@ -60,6 +64,7 @@ class PredictionType(StrEnum):
ENTITY_GROWTH = "entity_growth" # 实体增长预测 ENTITY_GROWTH = "entity_growth" # 实体增长预测
RELATION_EVOLUTION = "relation_evolution" # 关系演变预测 RELATION_EVOLUTION = "relation_evolution" # 关系演变预测
@dataclass @dataclass
class CustomModel: class CustomModel:
"""自定义模型""" """自定义模型"""
@@ -79,6 +84,7 @@ class CustomModel:
trained_at: str | None trained_at: str | None
created_by: str created_by: str
@dataclass @dataclass
class TrainingSample: class TrainingSample:
"""训练样本""" """训练样本"""
@@ -90,6 +96,7 @@ class TrainingSample:
metadata: dict metadata: dict
created_at: str created_at: str
@dataclass @dataclass
class MultimodalAnalysis: class MultimodalAnalysis:
"""多模态分析结果""" """多模态分析结果"""
@@ -106,6 +113,7 @@ class MultimodalAnalysis:
cost: float cost: float
created_at: str created_at: str
@dataclass @dataclass
class KnowledgeGraphRAG: class KnowledgeGraphRAG:
"""基于知识图谱的 RAG 配置""" """基于知识图谱的 RAG 配置"""
@@ -122,6 +130,7 @@ class KnowledgeGraphRAG:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class RAGQuery: class RAGQuery:
"""RAG 查询记录""" """RAG 查询记录"""
@@ -137,6 +146,7 @@ class RAGQuery:
latency_ms: int latency_ms: int
created_at: str created_at: str
@dataclass @dataclass
class PredictionModel: class PredictionModel:
"""预测模型""" """预测模型"""
@@ -156,6 +166,7 @@ class PredictionModel:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class PredictionResult: class PredictionResult:
"""预测结果""" """预测结果"""
@@ -171,6 +182,7 @@ class PredictionResult:
is_correct: bool | None is_correct: bool | None
created_at: str created_at: str
@dataclass @dataclass
class SmartSummary: class SmartSummary:
"""智能摘要""" """智能摘要"""
@@ -188,6 +200,7 @@ class SmartSummary:
tokens_used: int tokens_used: int
created_at: str created_at: str
class AIManager: class AIManager:
"""AI 能力管理主类""" """AI 能力管理主类"""
@@ -242,7 +255,8 @@ class AIManager:
""" """
INSERT INTO custom_models INSERT INTO custom_models
(id, tenant_id, name, description, model_type, status, training_data, (id, tenant_id, name, description, model_type, status, training_data,
hyperparameters, metrics, model_path, created_at, updated_at, trained_at, created_by) hyperparameters, metrics, model_path, created_at, updated_at,
trained_at, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@@ -846,7 +860,8 @@ class AIManager:
conn.execute( conn.execute(
""" """
INSERT INTO rag_queries INSERT INTO rag_queries
(id, rag_id, query, context, answer, sources, confidence, tokens_used, latency_ms, created_at) (id, rag_id, query, context, answer, sources, confidence,
tokens_used, latency_ms, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@@ -1077,8 +1092,9 @@ class AIManager:
conn.execute( conn.execute(
""" """
INSERT INTO prediction_models INSERT INTO prediction_models
(id, tenant_id, project_id, name, prediction_type, target_entity_type, features, (id, tenant_id, project_id, name, prediction_type, target_entity_type,
model_config, accuracy, last_trained_at, prediction_count, is_active, created_at, updated_at) features, model_config, accuracy, last_trained_at, prediction_count,
is_active, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@@ -1487,9 +1503,11 @@ class AIManager:
created_at=row["created_at"], created_at=row["created_at"],
) )
# Singleton instance # Singleton instance
_ai_manager = None _ai_manager = None
def get_ai_manager() -> AIManager: def get_ai_manager() -> AIManager:
global _ai_manager global _ai_manager
if _ai_manager is None: if _ai_manager is None:

View File

@@ -15,11 +15,13 @@ from enum import Enum
DB_PATH = os.getenv("DB_PATH", "/app/data/insightflow.db") DB_PATH = os.getenv("DB_PATH", "/app/data/insightflow.db")
class ApiKeyStatus(Enum): class ApiKeyStatus(Enum):
ACTIVE = "active" ACTIVE = "active"
REVOKED = "revoked" REVOKED = "revoked"
EXPIRED = "expired" EXPIRED = "expired"
@dataclass @dataclass
class ApiKey: class ApiKey:
id: str id: str
@@ -37,6 +39,7 @@ class ApiKey:
revoked_reason: str | None revoked_reason: str | None
total_calls: int = 0 total_calls: int = 0
class ApiKeyManager: class ApiKeyManager:
"""API Key 管理器""" """API Key 管理器"""
@@ -106,7 +109,8 @@ class ApiKeyManager:
CREATE INDEX IF NOT EXISTS idx_api_keys_owner ON api_keys(owner_id); CREATE INDEX IF NOT EXISTS idx_api_keys_owner ON api_keys(owner_id);
CREATE INDEX IF NOT EXISTS idx_api_logs_key_id ON api_call_logs(api_key_id); CREATE INDEX IF NOT EXISTS idx_api_logs_key_id ON api_call_logs(api_key_id);
CREATE INDEX IF NOT EXISTS idx_api_logs_created ON api_call_logs(created_at); CREATE INDEX IF NOT EXISTS idx_api_logs_created ON api_call_logs(created_at);
CREATE INDEX IF NOT EXISTS idx_api_stats_key_date ON api_call_stats(api_key_id, date); CREATE INDEX IF NOT EXISTS idx_api_stats_key_date
ON api_call_stats(api_key_id, date);
""") """)
conn.commit() conn.commit()
@@ -522,9 +526,11 @@ class ApiKeyManager:
total_calls=row["total_calls"], total_calls=row["total_calls"],
) )
# 全局实例 # 全局实例
_api_key_manager: ApiKeyManager | None = None _api_key_manager: ApiKeyManager | None = None
def get_api_key_manager() -> ApiKeyManager: def get_api_key_manager() -> ApiKeyManager:
"""获取 API Key 管理器实例""" """获取 API Key 管理器实例"""
global _api_key_manager global _api_key_manager

View File

@@ -11,6 +11,7 @@ from datetime import datetime, timedelta
from enum import Enum from enum import Enum
from typing import Any from typing import Any
class SharePermission(Enum): class SharePermission(Enum):
"""分享权限级别""" """分享权限级别"""
@@ -19,6 +20,7 @@ class SharePermission(Enum):
EDIT = "edit" # 可编辑 EDIT = "edit" # 可编辑
ADMIN = "admin" # 管理员 ADMIN = "admin" # 管理员
class CommentTargetType(Enum): class CommentTargetType(Enum):
"""评论目标类型""" """评论目标类型"""
@@ -27,6 +29,7 @@ class CommentTargetType(Enum):
TRANSCRIPT = "transcript" # 转录文本评论 TRANSCRIPT = "transcript" # 转录文本评论
PROJECT = "project" # 项目级评论 PROJECT = "project" # 项目级评论
class ChangeType(Enum): class ChangeType(Enum):
"""变更类型""" """变更类型"""
@@ -36,6 +39,7 @@ class ChangeType(Enum):
MERGE = "merge" # 合并 MERGE = "merge" # 合并
SPLIT = "split" # 拆分 SPLIT = "split" # 拆分
@dataclass @dataclass
class ProjectShare: class ProjectShare:
"""项目分享链接""" """项目分享链接"""
@@ -54,6 +58,7 @@ class ProjectShare:
allow_download: bool # 允许下载 allow_download: bool # 允许下载
allow_export: bool # 允许导出 allow_export: bool # 允许导出
@dataclass @dataclass
class Comment: class Comment:
"""评论/批注""" """评论/批注"""
@@ -74,6 +79,7 @@ class Comment:
mentions: list[str] # 提及的用户 mentions: list[str] # 提及的用户
attachments: list[dict] # 附件 attachments: list[dict] # 附件
@dataclass @dataclass
class ChangeRecord: class ChangeRecord:
"""变更记录""" """变更记录"""
@@ -95,6 +101,7 @@ class ChangeRecord:
reverted_at: str | None # 回滚时间 reverted_at: str | None # 回滚时间
reverted_by: str | None # 回滚者 reverted_by: str | None # 回滚者
@dataclass @dataclass
class TeamMember: class TeamMember:
"""团队成员""" """团队成员"""
@@ -110,6 +117,7 @@ class TeamMember:
last_active_at: str | None # 最后活跃时间 last_active_at: str | None # 最后活跃时间
permissions: list[str] # 具体权限列表 permissions: list[str] # 具体权限列表
@dataclass @dataclass
class TeamSpace: class TeamSpace:
"""团队空间""" """团队空间"""
@@ -124,6 +132,7 @@ class TeamSpace:
project_count: int project_count: int
settings: dict[str, Any] # 团队设置 settings: dict[str, Any] # 团队设置
class CollaborationManager: class CollaborationManager:
"""协作管理主类""" """协作管理主类"""
@@ -982,9 +991,11 @@ class CollaborationManager:
) )
self.db.conn.commit() self.db.conn.commit()
# 全局协作管理器实例 # 全局协作管理器实例
_collaboration_manager = None _collaboration_manager = None
def get_collaboration_manager(db_manager=None) -> None: def get_collaboration_manager(db_manager=None) -> None:
"""获取协作管理器单例""" """获取协作管理器单例"""
global _collaboration_manager global _collaboration_manager

View File

@@ -17,6 +17,7 @@ DB_PATH = os.getenv("DB_PATH", "/app/data/insightflow.db")
# Constants # Constants
UUID_LENGTH = 8 # UUID 截断长度 UUID_LENGTH = 8 # UUID 截断长度
@dataclass @dataclass
class Project: class Project:
id: str id: str
@@ -25,6 +26,7 @@ class Project:
created_at: str = "" created_at: str = ""
updated_at: str = "" updated_at: str = ""
@dataclass @dataclass
class Entity: class Entity:
id: str id: str
@@ -45,6 +47,7 @@ class Entity:
if self.attributes is None: if self.attributes is None:
self.attributes = {} self.attributes = {}
@dataclass @dataclass
class AttributeTemplate: class AttributeTemplate:
"""属性模板定义""" """属性模板定义"""
@@ -65,6 +68,7 @@ class AttributeTemplate:
if self.options is None: if self.options is None:
self.options = [] self.options = []
@dataclass @dataclass
class EntityAttribute: class EntityAttribute:
"""实体属性值""" """实体属性值"""
@@ -85,6 +89,7 @@ class EntityAttribute:
if self.options is None: if self.options is None:
self.options = [] self.options = []
@dataclass @dataclass
class AttributeHistory: class AttributeHistory:
"""属性变更历史""" """属性变更历史"""
@@ -98,6 +103,7 @@ class AttributeHistory:
changed_at: str = "" changed_at: str = ""
change_reason: str = "" change_reason: str = ""
@dataclass @dataclass
class EntityMention: class EntityMention:
id: str id: str
@@ -108,6 +114,7 @@ class EntityMention:
text_snippet: str text_snippet: str
confidence: float = 1.0 confidence: float = 1.0
class DatabaseManager: class DatabaseManager:
def __init__(self, db_path: str = DB_PATH): def __init__(self, db_path: str = DB_PATH):
self.db_path = db_path self.db_path = db_path
@@ -135,7 +142,8 @@ class DatabaseManager:
conn = self.get_conn() conn = self.get_conn()
now = datetime.now().isoformat() now = datetime.now().isoformat()
conn.execute( conn.execute(
"INSERT INTO projects (id, name, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?)", """INSERT INTO projects (id, name, description, created_at, updated_at)
VALUES (?, ?, ?, ?, ?)""",
(project_id, name, description, now, now), (project_id, name, description, now, now),
) )
conn.commit() conn.commit()
@@ -186,7 +194,8 @@ class DatabaseManager:
"""通过名称查找实体(用于对齐)""" """通过名称查找实体(用于对齐)"""
conn = self.get_conn() conn = self.get_conn()
row = conn.execute( row = conn.execute(
"SELECT * FROM entities WHERE project_id = ? AND (name = ? OR canonical_name = ? OR aliases LIKE ?)", """SELECT * FROM entities WHERE project_id = ?
AND (name = ? OR canonical_name = ? OR aliases LIKE ?)""",
(project_id, name, name, f'%"{name}"%'), (project_id, name, name, f'%"{name}"%'),
).fetchone() ).fetchone()
conn.close() conn.close()
@@ -322,8 +331,9 @@ class DatabaseManager:
def add_mention(self, mention: EntityMention) -> EntityMention: def add_mention(self, mention: EntityMention) -> EntityMention:
conn = self.get_conn() conn = self.get_conn()
conn.execute( conn.execute(
"""INSERT INTO entity_mentions (id, entity_id, transcript_id, start_pos, end_pos, text_snippet, confidence) """INSERT INTO entity_mentions
VALUES (?, ?, ?, ?, ?, ?, ?)""", (id, entity_id, transcript_id, start_pos, end_pos, text_snippet, confidence)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(mention.id, (mention.id,
mention.entity_id, mention.entity_id,
mention.transcript_id, mention.transcript_id,
@@ -359,7 +369,9 @@ class DatabaseManager:
conn = self.get_conn() conn = self.get_conn()
now = datetime.now().isoformat() now = datetime.now().isoformat()
conn.execute( conn.execute(
"INSERT INTO transcripts (id, project_id, filename, full_text, type, created_at) VALUES (?, ?, ?, ?, ?, ?)", """INSERT INTO transcripts
(id, project_id, filename, full_text, type, created_at)
VALUES (?, ?, ?, ?, ?, ?)""",
(transcript_id, (transcript_id,
project_id, project_id,
filename, filename,
@@ -412,8 +424,9 @@ class DatabaseManager:
now = datetime.now().isoformat() now = datetime.now().isoformat()
conn.execute( conn.execute(
"""INSERT INTO entity_relations """INSERT INTO entity_relations
(id, project_id, source_entity_id, target_entity_id, relation_type, evidence, transcript_id, created_at) (id, project_id, source_entity_id, target_entity_id, relation_type,
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", evidence, transcript_id, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
( (
relation_id, relation_id,
project_id, project_id,
@@ -494,7 +507,9 @@ class DatabaseManager:
term_id = str(uuid.uuid4())[:UUID_LENGTH] term_id = str(uuid.uuid4())[:UUID_LENGTH]
conn.execute( conn.execute(
"INSERT INTO glossary (id, project_id, term, pronunciation, frequency) VALUES (?, ?, ?, ?, ?)", """INSERT INTO glossary
(id, project_id, term, pronunciation, frequency)
VALUES (?, ?, ?, ?, ?)""",
(term_id, project_id, term, pronunciation, 1), (term_id, project_id, term, pronunciation, 1),
) )
conn.commit() conn.commit()
@@ -840,8 +855,9 @@ class DatabaseManager:
if old_value != attr.value: if old_value != attr.value:
conn.execute( conn.execute(
"""INSERT INTO attribute_history """INSERT INTO attribute_history
(id, entity_id, template_id, old_value, new_value, changed_by, changed_at, change_reason) (id, entity_id, template_id, old_value, new_value,
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", changed_by, changed_at, change_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
( (
str(uuid.uuid4())[:UUID_LENGTH], str(uuid.uuid4())[:UUID_LENGTH],
attr.entity_id, attr.entity_id,
@@ -856,12 +872,18 @@ class DatabaseManager:
conn.execute( conn.execute(
"""INSERT OR REPLACE INTO entity_attributes """INSERT OR REPLACE INTO entity_attributes
(id, entity_id, template_id, value, created_at, updated_at) (id, entity_id, template_id, value, created_at, updated_at)
VALUES ( VALUES (
COALESCE((SELECT id FROM entity_attributes WHERE entity_id = ? AND template_id = ?), ?), COALESCE(
?, ?, ?, (SELECT id FROM entity_attributes
COALESCE((SELECT created_at FROM entity_attributes WHERE entity_id = ? AND template_id = ?), ?), WHERE entity_id = ? AND template_id = ?), ?
?)""", ),
?, ?, ?,
COALESCE(
(SELECT created_at FROM entity_attributes
WHERE entity_id = ? AND template_id = ?), ?
),
?)""",
( (
attr.entity_id, attr.entity_id,
attr.template_id, attr.template_id,
@@ -912,15 +934,17 @@ class DatabaseManager:
): ):
conn = self.get_conn() conn = self.get_conn()
old_row = conn.execute( old_row = conn.execute(
"SELECT value FROM entity_attributes WHERE entity_id = ? AND template_id = ?", """SELECT value FROM entity_attributes
WHERE entity_id = ? AND template_id = ?""",
(entity_id, template_id), (entity_id, template_id),
).fetchone() ).fetchone()
if old_row: if old_row:
conn.execute( conn.execute(
"""INSERT INTO attribute_history """INSERT INTO attribute_history
(id, entity_id, template_id, old_value, new_value, changed_by, changed_at, change_reason) (id, entity_id, template_id, old_value, new_value,
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", changed_by, changed_at, change_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
( (
str(uuid.uuid4())[:UUID_LENGTH], str(uuid.uuid4())[:UUID_LENGTH],
entity_id, entity_id,
@@ -1107,8 +1131,9 @@ class DatabaseManager:
conn.execute( conn.execute(
"""INSERT INTO video_frames """INSERT INTO video_frames
(id, video_id, frame_number, timestamp, image_url, ocr_text, extracted_entities, created_at) (id, video_id, frame_number, timestamp, image_url, ocr_text,
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", extracted_entities, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
( (
frame_id, frame_id,
video_id, video_id,
@@ -1394,9 +1419,11 @@ class DatabaseManager:
conn.close() conn.close()
return stats return stats
# Singleton instance # Singleton instance
_db_manager = None _db_manager = None
def get_db_manager() -> DatabaseManager: def get_db_manager() -> DatabaseManager:
global _db_manager global _db_manager
if _db_manager is None: if _db_manager is None:

View File

@@ -21,6 +21,7 @@ from enum import StrEnum
# Database path # Database path
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db") DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
class SDKLanguage(StrEnum): class SDKLanguage(StrEnum):
"""SDK 语言类型""" """SDK 语言类型"""
@@ -31,6 +32,7 @@ class SDKLanguage(StrEnum):
JAVA = "java" JAVA = "java"
RUST = "rust" RUST = "rust"
class SDKStatus(StrEnum): class SDKStatus(StrEnum):
"""SDK 状态""" """SDK 状态"""
@@ -40,6 +42,7 @@ class SDKStatus(StrEnum):
DEPRECATED = "deprecated" # 已弃用 DEPRECATED = "deprecated" # 已弃用
ARCHIVED = "archived" # 已归档 ARCHIVED = "archived" # 已归档
class TemplateCategory(StrEnum): class TemplateCategory(StrEnum):
"""模板分类""" """模板分类"""
@@ -50,6 +53,7 @@ class TemplateCategory(StrEnum):
TECH = "tech" # 科技 TECH = "tech" # 科技
GENERAL = "general" # 通用 GENERAL = "general" # 通用
class TemplateStatus(StrEnum): class TemplateStatus(StrEnum):
"""模板状态""" """模板状态"""
@@ -59,6 +63,7 @@ class TemplateStatus(StrEnum):
PUBLISHED = "published" # 已发布 PUBLISHED = "published" # 已发布
UNLISTED = "unlisted" # 未列出 UNLISTED = "unlisted" # 未列出
class PluginStatus(StrEnum): class PluginStatus(StrEnum):
"""插件状态""" """插件状态"""
@@ -69,6 +74,7 @@ class PluginStatus(StrEnum):
PUBLISHED = "published" # 已发布 PUBLISHED = "published" # 已发布
SUSPENDED = "suspended" # 已暂停 SUSPENDED = "suspended" # 已暂停
class PluginCategory(StrEnum): class PluginCategory(StrEnum):
"""插件分类""" """插件分类"""
@@ -79,6 +85,7 @@ class PluginCategory(StrEnum):
SECURITY = "security" # 安全 SECURITY = "security" # 安全
CUSTOM = "custom" # 自定义 CUSTOM = "custom" # 自定义
class DeveloperStatus(StrEnum): class DeveloperStatus(StrEnum):
"""开发者认证状态""" """开发者认证状态"""
@@ -88,6 +95,7 @@ class DeveloperStatus(StrEnum):
CERTIFIED = "certified" # 已认证(高级) CERTIFIED = "certified" # 已认证(高级)
SUSPENDED = "suspended" # 已暂停 SUSPENDED = "suspended" # 已暂停
@dataclass @dataclass
class SDKRelease: class SDKRelease:
"""SDK 发布""" """SDK 发布"""
@@ -113,6 +121,7 @@ class SDKRelease:
published_at: str | None published_at: str | None
created_by: str created_by: str
@dataclass @dataclass
class SDKVersion: class SDKVersion:
"""SDK 版本历史""" """SDK 版本历史"""
@@ -129,6 +138,7 @@ class SDKVersion:
download_count: int download_count: int
created_at: str created_at: str
@dataclass @dataclass
class TemplateMarketItem: class TemplateMarketItem:
"""模板市场项目""" """模板市场项目"""
@@ -160,6 +170,7 @@ class TemplateMarketItem:
updated_at: str updated_at: str
published_at: str | None published_at: str | None
@dataclass @dataclass
class TemplateReview: class TemplateReview:
"""模板评价""" """模板评价"""
@@ -175,6 +186,7 @@ class TemplateReview:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class PluginMarketItem: class PluginMarketItem:
"""插件市场项目""" """插件市场项目"""
@@ -213,6 +225,7 @@ class PluginMarketItem:
reviewed_at: str | None reviewed_at: str | None
review_notes: str | None review_notes: str | None
@dataclass @dataclass
class PluginReview: class PluginReview:
"""插件评价""" """插件评价"""
@@ -228,6 +241,7 @@ class PluginReview:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class DeveloperProfile: class DeveloperProfile:
"""开发者档案""" """开发者档案"""
@@ -251,6 +265,7 @@ class DeveloperProfile:
updated_at: str updated_at: str
verified_at: str | None verified_at: str | None
@dataclass @dataclass
class DeveloperRevenue: class DeveloperRevenue:
"""开发者收益""" """开发者收益"""
@@ -268,6 +283,7 @@ class DeveloperRevenue:
transaction_id: str transaction_id: str
created_at: str created_at: str
@dataclass @dataclass
class CodeExample: class CodeExample:
"""代码示例""" """代码示例"""
@@ -290,6 +306,7 @@ class CodeExample:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class APIDocumentation: class APIDocumentation:
"""API 文档生成记录""" """API 文档生成记录"""
@@ -303,6 +320,7 @@ class APIDocumentation:
generated_at: str generated_at: str
generated_by: str generated_by: str
@dataclass @dataclass
class DeveloperPortalConfig: class DeveloperPortalConfig:
"""开发者门户配置""" """开发者门户配置"""
@@ -326,6 +344,7 @@ class DeveloperPortalConfig:
created_at: str created_at: str
updated_at: str updated_at: str
class DeveloperEcosystemManager: class DeveloperEcosystemManager:
"""开发者生态系统管理主类""" """开发者生态系统管理主类"""
@@ -2033,9 +2052,11 @@ class DeveloperEcosystemManager:
updated_at=row["updated_at"], updated_at=row["updated_at"],
) )
# Singleton instance # Singleton instance
_developer_ecosystem_manager = None _developer_ecosystem_manager = None
def get_developer_ecosystem_manager() -> DeveloperEcosystemManager: def get_developer_ecosystem_manager() -> DeveloperEcosystemManager:
"""获取开发者生态系统管理器单例""" """获取开发者生态系统管理器单例"""
global _developer_ecosystem_manager global _developer_ecosystem_manager

View File

@@ -7,6 +7,7 @@ Document Processor - Phase 3
import io import io
import os import os
class DocumentProcessor: class DocumentProcessor:
"""文档处理器 - 提取 PDF/DOCX 文本""" """文档处理器 - 提取 PDF/DOCX 文本"""
@@ -156,6 +157,8 @@ class DocumentProcessor:
return ext in self.supported_formats return ext in self.supported_formats
# 简单的文本提取器(不需要外部依赖) # 简单的文本提取器(不需要外部依赖)
class SimpleTextExtractor: class SimpleTextExtractor:
"""简单的文本提取器,用于测试""" """简单的文本提取器,用于测试"""
@@ -171,6 +174,7 @@ class SimpleTextExtractor:
return content.decode("latin-1", errors="ignore") return content.decode("latin-1", errors="ignore")
if __name__ == "__main__": if __name__ == "__main__":
# 测试 # 测试
processor = DocumentProcessor() processor = DocumentProcessor()

View File

@@ -21,6 +21,7 @@ from typing import Any
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SSOProvider(StrEnum): class SSOProvider(StrEnum):
"""SSO 提供商类型""" """SSO 提供商类型"""
@@ -32,6 +33,7 @@ class SSOProvider(StrEnum):
GOOGLE = "google" # Google Workspace GOOGLE = "google" # Google Workspace
CUSTOM_SAML = "custom_saml" # 自定义 SAML CUSTOM_SAML = "custom_saml" # 自定义 SAML
class SSOStatus(StrEnum): class SSOStatus(StrEnum):
"""SSO 配置状态""" """SSO 配置状态"""
@@ -40,6 +42,7 @@ class SSOStatus(StrEnum):
ACTIVE = "active" # 已启用 ACTIVE = "active" # 已启用
ERROR = "error" # 配置错误 ERROR = "error" # 配置错误
class SCIMSyncStatus(StrEnum): class SCIMSyncStatus(StrEnum):
"""SCIM 同步状态""" """SCIM 同步状态"""
@@ -48,6 +51,7 @@ class SCIMSyncStatus(StrEnum):
SUCCESS = "success" # 同步成功 SUCCESS = "success" # 同步成功
FAILED = "failed" # 同步失败 FAILED = "failed" # 同步失败
class AuditLogExportFormat(StrEnum): class AuditLogExportFormat(StrEnum):
"""审计日志导出格式""" """审计日志导出格式"""
@@ -56,6 +60,7 @@ class AuditLogExportFormat(StrEnum):
PDF = "pdf" PDF = "pdf"
XLSX = "xlsx" XLSX = "xlsx"
class DataRetentionAction(StrEnum): class DataRetentionAction(StrEnum):
"""数据保留策略动作""" """数据保留策略动作"""
@@ -63,6 +68,7 @@ class DataRetentionAction(StrEnum):
DELETE = "delete" # 删除 DELETE = "delete" # 删除
ANONYMIZE = "anonymize" # 匿名化 ANONYMIZE = "anonymize" # 匿名化
class ComplianceStandard(StrEnum): class ComplianceStandard(StrEnum):
"""合规标准""" """合规标准"""
@@ -72,6 +78,7 @@ class ComplianceStandard(StrEnum):
HIPAA = "hipaa" HIPAA = "hipaa"
PCI_DSS = "pci_dss" PCI_DSS = "pci_dss"
@dataclass @dataclass
class SSOConfig: class SSOConfig:
"""SSO 配置数据类""" """SSO 配置数据类"""
@@ -104,6 +111,7 @@ class SSOConfig:
last_tested_at: datetime | None last_tested_at: datetime | None
last_error: str | None last_error: str | None
@dataclass @dataclass
class SCIMConfig: class SCIMConfig:
"""SCIM 配置数据类""" """SCIM 配置数据类"""
@@ -128,6 +136,7 @@ class SCIMConfig:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class SCIMUser: class SCIMUser:
"""SCIM 用户数据类""" """SCIM 用户数据类"""
@@ -147,6 +156,7 @@ class SCIMUser:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class AuditLogExport: class AuditLogExport:
"""审计日志导出记录""" """审计日志导出记录"""
@@ -171,6 +181,7 @@ class AuditLogExport:
completed_at: datetime | None completed_at: datetime | None
error_message: str | None error_message: str | None
@dataclass @dataclass
class DataRetentionPolicy: class DataRetentionPolicy:
"""数据保留策略""" """数据保留策略"""
@@ -198,6 +209,7 @@ class DataRetentionPolicy:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class DataRetentionJob: class DataRetentionJob:
"""数据保留任务""" """数据保留任务"""
@@ -215,6 +227,7 @@ class DataRetentionJob:
details: dict[str, Any] details: dict[str, Any]
created_at: datetime created_at: datetime
@dataclass @dataclass
class SAMLAuthRequest: class SAMLAuthRequest:
"""SAML 认证请求""" """SAML 认证请求"""
@@ -229,6 +242,7 @@ class SAMLAuthRequest:
used: bool used: bool
used_at: datetime | None used_at: datetime | None
@dataclass @dataclass
class SAMLAuthResponse: class SAMLAuthResponse:
"""SAML 认证响应""" """SAML 认证响应"""
@@ -245,6 +259,7 @@ class SAMLAuthResponse:
processed_at: datetime | None processed_at: datetime | None
created_at: datetime created_at: datetime
class EnterpriseManager: class EnterpriseManager:
"""企业级功能管理器""" """企业级功能管理器"""
@@ -2185,9 +2200,11 @@ class EnterpriseManager:
), ),
) )
# 全局实例 # 全局实例
_enterprise_manager = None _enterprise_manager = None
def get_enterprise_manager(db_path: str = "insightflow.db") -> EnterpriseManager: def get_enterprise_manager(db_path: str = "insightflow.db") -> EnterpriseManager:
"""获取 EnterpriseManager 单例""" """获取 EnterpriseManager 单例"""
global _enterprise_manager global _enterprise_manager

View File

@@ -15,6 +15,7 @@ import numpy as np
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "") KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding") KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
@dataclass @dataclass
class EntityEmbedding: class EntityEmbedding:
entity_id: str entity_id: str
@@ -22,6 +23,7 @@ class EntityEmbedding:
definition: str definition: str
embedding: list[float] embedding: list[float]
class EntityAligner: class EntityAligner:
"""实体对齐器 - 使用 embedding 进行相似度匹配""" """实体对齐器 - 使用 embedding 进行相似度匹配"""
@@ -64,7 +66,7 @@ class EntityAligner:
self.embedding_cache[cache_key] = embedding self.embedding_cache[cache_key] = embedding
return embedding return embedding
except Exception as e: except (httpx.HTTPError, json.JSONDecodeError, KeyError) as e:
print(f"Embedding API failed: {e}") print(f"Embedding API failed: {e}")
return None return None
@@ -311,12 +313,14 @@ class EntityAligner:
if json_match: if json_match:
data = json.loads(json_match.group()) data = json.loads(json_match.group())
return data.get("aliases", []) return data.get("aliases", [])
except Exception as e: except (httpx.HTTPError, json.JSONDecodeError, KeyError) as e:
print(f"Alias suggestion failed: {e}") print(f"Alias suggestion failed: {e}")
return [] return []
# 简单的字符串相似度计算(不使用 embedding # 简单的字符串相似度计算(不使用 embedding
def simple_similarity(str1: str, str2: str) -> float: def simple_similarity(str1: str, str2: str) -> float:
""" """
计算两个字符串的简单相似度 计算两个字符串的简单相似度
@@ -347,6 +351,7 @@ def simple_similarity(str1: str, str2: str) -> float:
return SequenceMatcher(None, s1, s2).ratio() return SequenceMatcher(None, s1, s2).ratio()
if __name__ == "__main__": if __name__ == "__main__":
# 测试 # 测试
aligner = EntityAligner() aligner = EntityAligner()

View File

@@ -36,6 +36,7 @@ try:
except ImportError: except ImportError:
REPORTLAB_AVAILABLE = False REPORTLAB_AVAILABLE = False
@dataclass @dataclass
class ExportEntity: class ExportEntity:
id: str id: str
@@ -46,6 +47,7 @@ class ExportEntity:
mention_count: int mention_count: int
attributes: dict[str, Any] attributes: dict[str, Any]
@dataclass @dataclass
class ExportRelation: class ExportRelation:
id: str id: str
@@ -55,6 +57,7 @@ class ExportRelation:
confidence: float confidence: float
evidence: str evidence: str
@dataclass @dataclass
class ExportTranscript: class ExportTranscript:
id: str id: str
@@ -64,6 +67,7 @@ class ExportTranscript:
segments: list[dict] segments: list[dict]
entity_mentions: list[dict] entity_mentions: list[dict]
class ExportManager: class ExportManager:
"""导出管理器 - 处理各种导出需求""" """导出管理器 - 处理各种导出需求"""
@@ -611,9 +615,11 @@ class ExportManager:
return json.dumps(data, ensure_ascii=False, indent=2) return json.dumps(data, ensure_ascii=False, indent=2)
# 全局导出管理器实例 # 全局导出管理器实例
_export_manager = None _export_manager = None
def get_export_manager(db_manager=None) -> None: def get_export_manager(db_manager=None) -> None:
"""获取导出管理器实例""" """获取导出管理器实例"""
global _export_manager global _export_manager

View File

@@ -28,6 +28,7 @@ import httpx
# Database path # Database path
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db") DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
class EventType(StrEnum): class EventType(StrEnum):
"""事件类型""" """事件类型"""
@@ -43,6 +44,7 @@ class EventType(StrEnum):
INVITE_ACCEPTED = "invite_accepted" # 接受邀请 INVITE_ACCEPTED = "invite_accepted" # 接受邀请
REFERRAL_REWARD = "referral_reward" # 推荐奖励 REFERRAL_REWARD = "referral_reward" # 推荐奖励
class ExperimentStatus(StrEnum): class ExperimentStatus(StrEnum):
"""实验状态""" """实验状态"""
@@ -52,6 +54,7 @@ class ExperimentStatus(StrEnum):
COMPLETED = "completed" # 已完成 COMPLETED = "completed" # 已完成
ARCHIVED = "archived" # 已归档 ARCHIVED = "archived" # 已归档
class TrafficAllocationType(StrEnum): class TrafficAllocationType(StrEnum):
"""流量分配类型""" """流量分配类型"""
@@ -59,6 +62,7 @@ class TrafficAllocationType(StrEnum):
STRATIFIED = "stratified" # 分层分配 STRATIFIED = "stratified" # 分层分配
TARGETED = "targeted" # 定向分配 TARGETED = "targeted" # 定向分配
class EmailTemplateType(StrEnum): class EmailTemplateType(StrEnum):
"""邮件模板类型""" """邮件模板类型"""
@@ -70,6 +74,7 @@ class EmailTemplateType(StrEnum):
REFERRAL = "referral" # 推荐邀请 REFERRAL = "referral" # 推荐邀请
NEWSLETTER = "newsletter" # 新闻通讯 NEWSLETTER = "newsletter" # 新闻通讯
class EmailStatus(StrEnum): class EmailStatus(StrEnum):
"""邮件状态""" """邮件状态"""
@@ -83,6 +88,7 @@ class EmailStatus(StrEnum):
BOUNCED = "bounced" # 退信 BOUNCED = "bounced" # 退信
FAILED = "failed" # 失败 FAILED = "failed" # 失败
class WorkflowTriggerType(StrEnum): class WorkflowTriggerType(StrEnum):
"""工作流触发类型""" """工作流触发类型"""
@@ -94,6 +100,7 @@ class WorkflowTriggerType(StrEnum):
MILESTONE = "milestone" # 里程碑 MILESTONE = "milestone" # 里程碑
CUSTOM_EVENT = "custom_event" # 自定义事件 CUSTOM_EVENT = "custom_event" # 自定义事件
class ReferralStatus(StrEnum): class ReferralStatus(StrEnum):
"""推荐状态""" """推荐状态"""
@@ -102,6 +109,7 @@ class ReferralStatus(StrEnum):
REWARDED = "rewarded" # 已奖励 REWARDED = "rewarded" # 已奖励
EXPIRED = "expired" # 已过期 EXPIRED = "expired" # 已过期
@dataclass @dataclass
class AnalyticsEvent: class AnalyticsEvent:
"""分析事件""" """分析事件"""
@@ -120,6 +128,7 @@ class AnalyticsEvent:
utm_medium: str | None utm_medium: str | None
utm_campaign: str | None utm_campaign: str | None
@dataclass @dataclass
class UserProfile: class UserProfile:
"""用户画像""" """用户画像"""
@@ -139,6 +148,7 @@ class UserProfile:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class Funnel: class Funnel:
"""转化漏斗""" """转化漏斗"""
@@ -151,6 +161,7 @@ class Funnel:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class FunnelAnalysis: class FunnelAnalysis:
"""漏斗分析结果""" """漏斗分析结果"""
@@ -163,6 +174,7 @@ class FunnelAnalysis:
overall_conversion: float # 总体转化率 overall_conversion: float # 总体转化率
drop_off_points: list[dict] # 流失点 drop_off_points: list[dict] # 流失点
@dataclass @dataclass
class Experiment: class Experiment:
"""A/B 测试实验""" """A/B 测试实验"""
@@ -187,6 +199,7 @@ class Experiment:
updated_at: datetime updated_at: datetime
created_by: str created_by: str
@dataclass @dataclass
class ExperimentResult: class ExperimentResult:
"""实验结果""" """实验结果"""
@@ -204,6 +217,7 @@ class ExperimentResult:
uplift: float # 提升幅度 uplift: float # 提升幅度
created_at: datetime created_at: datetime
@dataclass @dataclass
class EmailTemplate: class EmailTemplate:
"""邮件模板""" """邮件模板"""
@@ -224,6 +238,7 @@ class EmailTemplate:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class EmailCampaign: class EmailCampaign:
"""邮件营销活动""" """邮件营销活动"""
@@ -245,6 +260,7 @@ class EmailCampaign:
completed_at: datetime | None completed_at: datetime | None
created_at: datetime created_at: datetime
@dataclass @dataclass
class EmailLog: class EmailLog:
"""邮件发送记录""" """邮件发送记录"""
@@ -266,6 +282,7 @@ class EmailLog:
error_message: str | None error_message: str | None
created_at: datetime created_at: datetime
@dataclass @dataclass
class AutomationWorkflow: class AutomationWorkflow:
"""自动化工作流""" """自动化工作流"""
@@ -282,6 +299,7 @@ class AutomationWorkflow:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class ReferralProgram: class ReferralProgram:
"""推荐计划""" """推荐计划"""
@@ -301,6 +319,7 @@ class ReferralProgram:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class Referral: class Referral:
"""推荐记录""" """推荐记录"""
@@ -321,6 +340,7 @@ class Referral:
expires_at: datetime expires_at: datetime
created_at: datetime created_at: datetime
@dataclass @dataclass
class TeamIncentive: class TeamIncentive:
"""团队升级激励""" """团队升级激励"""
@@ -338,6 +358,7 @@ class TeamIncentive:
is_active: bool is_active: bool
created_at: datetime created_at: datetime
class GrowthManager: class GrowthManager:
"""运营与增长管理主类""" """运营与增长管理主类"""
@@ -2126,9 +2147,11 @@ class GrowthManager:
created_at=row["created_at"], created_at=row["created_at"],
) )
# Singleton instance # Singleton instance
_growth_manager = None _growth_manager = None
def get_growth_manager() -> GrowthManager: def get_growth_manager() -> GrowthManager:
global _growth_manager global _growth_manager
if _growth_manager is None: if _growth_manager is None:

View File

@@ -36,6 +36,7 @@ try:
except ImportError: except ImportError:
PYTESSERACT_AVAILABLE = False PYTESSERACT_AVAILABLE = False
@dataclass @dataclass
class ImageEntity: class ImageEntity:
"""图片中检测到的实体""" """图片中检测到的实体"""
@@ -45,6 +46,7 @@ class ImageEntity:
confidence: float confidence: float
bbox: tuple[int, int, int, int] | None = None # (x, y, width, height) bbox: tuple[int, int, int, int] | None = None # (x, y, width, height)
@dataclass @dataclass
class ImageRelation: class ImageRelation:
"""图片中检测到的关系""" """图片中检测到的关系"""
@@ -54,6 +56,7 @@ class ImageRelation:
relation_type: str relation_type: str
confidence: float confidence: float
@dataclass @dataclass
class ImageProcessingResult: class ImageProcessingResult:
"""图片处理结果""" """图片处理结果"""
@@ -69,6 +72,7 @@ class ImageProcessingResult:
success: bool success: bool
error_message: str = "" error_message: str = ""
@dataclass @dataclass
class BatchProcessingResult: class BatchProcessingResult:
"""批量图片处理结果""" """批量图片处理结果"""
@@ -78,6 +82,7 @@ class BatchProcessingResult:
success_count: int success_count: int
failed_count: int failed_count: int
class ImageProcessor: class ImageProcessor:
"""图片处理器 - 处理各种类型图片""" """图片处理器 - 处理各种类型图片"""
@@ -551,9 +556,11 @@ class ImageProcessor:
print(f"Thumbnail generation error: {e}") print(f"Thumbnail generation error: {e}")
return image_data return image_data
# Singleton instance # Singleton instance
_image_processor = None _image_processor = None
def get_image_processor(temp_dir: str = None) -> ImageProcessor: def get_image_processor(temp_dir: str = None) -> ImageProcessor:
"""获取图片处理器单例""" """获取图片处理器单例"""
global _image_processor global _image_processor

View File

@@ -15,6 +15,7 @@ import httpx
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "") KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding") KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
class ReasoningType(Enum): class ReasoningType(Enum):
"""推理类型""" """推理类型"""
@@ -24,6 +25,7 @@ class ReasoningType(Enum):
COMPARATIVE = "comparative" # 对比推理 COMPARATIVE = "comparative" # 对比推理
SUMMARY = "summary" # 总结推理 SUMMARY = "summary" # 总结推理
@dataclass @dataclass
class ReasoningResult: class ReasoningResult:
"""推理结果""" """推理结果"""
@@ -35,6 +37,7 @@ class ReasoningResult:
related_entities: list[str] # 相关实体 related_entities: list[str] # 相关实体
gaps: list[str] # 知识缺口 gaps: list[str] # 知识缺口
@dataclass @dataclass
class InferencePath: class InferencePath:
"""推理路径""" """推理路径"""
@@ -44,6 +47,7 @@ class InferencePath:
path: list[dict] # 路径上的节点和关系 path: list[dict] # 路径上的节点和关系
strength: float # 路径强度 strength: float # 路径强度
class KnowledgeReasoner: class KnowledgeReasoner:
"""知识推理引擎""" """知识推理引擎"""
@@ -498,9 +502,11 @@ class KnowledgeReasoner:
"confidence": 0.5, "confidence": 0.5,
} }
# Singleton instance # Singleton instance
_reasoner = None _reasoner = None
def get_knowledge_reasoner() -> KnowledgeReasoner: def get_knowledge_reasoner() -> KnowledgeReasoner:
global _reasoner global _reasoner
if _reasoner is None: if _reasoner is None:

View File

@@ -15,11 +15,13 @@ import httpx
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "") KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding") KIMI_BASE_URL = os.getenv("KIMI_BASE_URL", "https://api.kimi.com/coding")
@dataclass @dataclass
class ChatMessage: class ChatMessage:
role: str role: str
content: str content: str
@dataclass @dataclass
class EntityExtractionResult: class EntityExtractionResult:
name: str name: str
@@ -27,6 +29,7 @@ class EntityExtractionResult:
definition: str definition: str
confidence: float confidence: float
@dataclass @dataclass
class RelationExtractionResult: class RelationExtractionResult:
source: str source: str
@@ -34,6 +37,7 @@ class RelationExtractionResult:
type: str type: str
confidence: float confidence: float
class LLMClient: class LLMClient:
"""Kimi API 客户端""" """Kimi API 客户端"""
@@ -254,9 +258,11 @@ class LLMClient:
messages = [ChatMessage(role="user", content=prompt)] messages = [ChatMessage(role="user", content=prompt)]
return await self.chat(messages, temperature=0.3) return await self.chat(messages, temperature=0.3)
# Singleton instance # Singleton instance
_llm_client = None _llm_client = None
def get_llm_client() -> LLMClient: def get_llm_client() -> LLMClient:
global _llm_client global _llm_client
if _llm_client is None: if _llm_client is None:

View File

@@ -35,6 +35,7 @@ except ImportError:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class LanguageCode(StrEnum): class LanguageCode(StrEnum):
"""支持的语言代码""" """支持的语言代码"""
@@ -51,6 +52,7 @@ class LanguageCode(StrEnum):
AR = "ar" AR = "ar"
HI = "hi" HI = "hi"
class RegionCode(StrEnum): class RegionCode(StrEnum):
"""区域代码""" """区域代码"""
@@ -62,6 +64,7 @@ class RegionCode(StrEnum):
LATIN_AMERICA = "latam" LATIN_AMERICA = "latam"
MIDDLE_EAST = "me" MIDDLE_EAST = "me"
class DataCenterRegion(StrEnum): class DataCenterRegion(StrEnum):
"""数据中心区域""" """数据中心区域"""
@@ -75,6 +78,7 @@ class DataCenterRegion(StrEnum):
CN_NORTH = "cn-north" CN_NORTH = "cn-north"
CN_EAST = "cn-east" CN_EAST = "cn-east"
class PaymentProvider(StrEnum): class PaymentProvider(StrEnum):
"""支付提供商""" """支付提供商"""
@@ -91,6 +95,7 @@ class PaymentProvider(StrEnum):
SEPA = "sepa" SEPA = "sepa"
UNIONPAY = "unionpay" UNIONPAY = "unionpay"
class CalendarType(StrEnum): class CalendarType(StrEnum):
"""日历类型""" """日历类型"""
@@ -102,6 +107,7 @@ class CalendarType(StrEnum):
PERSIAN = "persian" PERSIAN = "persian"
BUDDHIST = "buddhist" BUDDHIST = "buddhist"
@dataclass @dataclass
class Translation: class Translation:
id: str id: str
@@ -116,6 +122,7 @@ class Translation:
reviewed_by: str | None reviewed_by: str | None
reviewed_at: datetime | None reviewed_at: datetime | None
@dataclass @dataclass
class LanguageConfig: class LanguageConfig:
code: str code: str
@@ -133,6 +140,7 @@ class LanguageConfig:
first_day_of_week: int first_day_of_week: int
calendar_type: str calendar_type: str
@dataclass @dataclass
class DataCenter: class DataCenter:
id: str id: str
@@ -147,6 +155,7 @@ class DataCenter:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class TenantDataCenterMapping: class TenantDataCenterMapping:
id: str id: str
@@ -158,6 +167,7 @@ class TenantDataCenterMapping:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class LocalizedPaymentMethod: class LocalizedPaymentMethod:
id: str id: str
@@ -175,6 +185,7 @@ class LocalizedPaymentMethod:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class CountryConfig: class CountryConfig:
code: str code: str
@@ -196,6 +207,7 @@ class CountryConfig:
vat_rate: float | None vat_rate: float | None
is_active: bool is_active: bool
@dataclass @dataclass
class TimezoneConfig: class TimezoneConfig:
id: str id: str
@@ -206,6 +218,7 @@ class TimezoneConfig:
region: str region: str
is_active: bool is_active: bool
@dataclass @dataclass
class CurrencyConfig: class CurrencyConfig:
code: str code: str
@@ -217,6 +230,7 @@ class CurrencyConfig:
thousands_separator: str thousands_separator: str
is_active: bool is_active: bool
@dataclass @dataclass
class LocalizationSettings: class LocalizationSettings:
id: str id: str
@@ -236,6 +250,7 @@ class LocalizationSettings:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
class LocalizationManager: class LocalizationManager:
DEFAULT_LANGUAGES = { DEFAULT_LANGUAGES = {
LanguageCode.EN: { LanguageCode.EN: {
@@ -1683,8 +1698,10 @@ class LocalizationManager:
), ),
) )
_localization_manager = None _localization_manager = None
def get_localization_manager(db_path: str = "insightflow.db") -> LocalizationManager: def get_localization_manager(db_path: str = "insightflow.db") -> LocalizationManager:
global _localization_manager global _localization_manager
if _localization_manager is None: if _localization_manager is None:

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@ try:
except ImportError: except ImportError:
NUMPY_AVAILABLE = False NUMPY_AVAILABLE = False
@dataclass @dataclass
class MultimodalEntity: class MultimodalEntity:
"""多模态实体""" """多模态实体"""
@@ -35,6 +36,7 @@ class MultimodalEntity:
if self.modality_features is None: if self.modality_features is None:
self.modality_features = {} self.modality_features = {}
@dataclass @dataclass
class EntityLink: class EntityLink:
"""实体关联""" """实体关联"""
@@ -49,6 +51,7 @@ class EntityLink:
confidence: float confidence: float
evidence: str evidence: str
@dataclass @dataclass
class AlignmentResult: class AlignmentResult:
"""对齐结果""" """对齐结果"""
@@ -59,6 +62,7 @@ class AlignmentResult:
match_type: str # exact, fuzzy, embedding match_type: str # exact, fuzzy, embedding
confidence: float confidence: float
@dataclass @dataclass
class FusionResult: class FusionResult:
"""知识融合结果""" """知识融合结果"""
@@ -69,6 +73,7 @@ class FusionResult:
source_modalities: list[str] source_modalities: list[str]
confidence: float confidence: float
class MultimodalEntityLinker: class MultimodalEntityLinker:
"""多模态实体关联器 - 跨模态实体对齐和知识融合""" """多模态实体关联器 - 跨模态实体对齐和知识融合"""
@@ -510,9 +515,11 @@ class MultimodalEntityLinker:
else 0, else 0,
} }
# Singleton instance # Singleton instance
_multimodal_entity_linker = None _multimodal_entity_linker = None
def get_multimodal_entity_linker(similarity_threshold: float = 0.85) -> MultimodalEntityLinker: def get_multimodal_entity_linker(similarity_threshold: float = 0.85) -> MultimodalEntityLinker:
"""获取多模态实体关联器单例""" """获取多模态实体关联器单例"""
global _multimodal_entity_linker global _multimodal_entity_linker

View File

@@ -38,6 +38,7 @@ try:
except ImportError: except ImportError:
FFMPEG_AVAILABLE = False FFMPEG_AVAILABLE = False
@dataclass @dataclass
class VideoFrame: class VideoFrame:
"""视频关键帧数据类""" """视频关键帧数据类"""
@@ -55,6 +56,7 @@ class VideoFrame:
if self.entities_detected is None: if self.entities_detected is None:
self.entities_detected = [] self.entities_detected = []
@dataclass @dataclass
class VideoInfo: class VideoInfo:
"""视频信息数据类""" """视频信息数据类"""
@@ -78,6 +80,7 @@ class VideoInfo:
if self.metadata is None: if self.metadata is None:
self.metadata = {} self.metadata = {}
@dataclass @dataclass
class VideoProcessingResult: class VideoProcessingResult:
"""视频处理结果""" """视频处理结果"""
@@ -90,6 +93,7 @@ class VideoProcessingResult:
success: bool success: bool
error_message: str = "" error_message: str = ""
class MultimodalProcessor: class MultimodalProcessor:
"""多模态处理器 - 处理视频文件""" """多模态处理器 - 处理视频文件"""
@@ -448,9 +452,11 @@ class MultimodalProcessor:
shutil.rmtree(dir_path) shutil.rmtree(dir_path)
os.makedirs(dir_path, exist_ok=True) os.makedirs(dir_path, exist_ok=True)
# Singleton instance # Singleton instance
_multimodal_processor = None _multimodal_processor = None
def get_multimodal_processor(temp_dir: str = None, frame_interval: int = 5) -> MultimodalProcessor: def get_multimodal_processor(temp_dir: str = None, frame_interval: int = 5) -> MultimodalProcessor:
"""获取多模态处理器单例""" """获取多模态处理器单例"""
global _multimodal_processor global _multimodal_processor

View File

@@ -26,6 +26,7 @@ except ImportError:
NEO4J_AVAILABLE = False NEO4J_AVAILABLE = False
logger.warning("Neo4j driver not installed. Neo4j features will be disabled.") logger.warning("Neo4j driver not installed. Neo4j features will be disabled.")
@dataclass @dataclass
class GraphEntity: class GraphEntity:
"""图数据库中的实体节点""" """图数据库中的实体节点"""
@@ -44,6 +45,7 @@ class GraphEntity:
if self.properties is None: if self.properties is None:
self.properties = {} self.properties = {}
@dataclass @dataclass
class GraphRelation: class GraphRelation:
"""图数据库中的关系边""" """图数据库中的关系边"""
@@ -59,6 +61,7 @@ class GraphRelation:
if self.properties is None: if self.properties is None:
self.properties = {} self.properties = {}
@dataclass @dataclass
class PathResult: class PathResult:
"""路径查询结果""" """路径查询结果"""
@@ -68,6 +71,7 @@ class PathResult:
length: int length: int
total_weight: float = 0.0 total_weight: float = 0.0
@dataclass @dataclass
class CommunityResult: class CommunityResult:
"""社区发现结果""" """社区发现结果"""
@@ -77,6 +81,7 @@ class CommunityResult:
size: int size: int
density: float = 0.0 density: float = 0.0
@dataclass @dataclass
class CentralityResult: class CentralityResult:
"""中心性分析结果""" """中心性分析结果"""
@@ -86,6 +91,7 @@ class CentralityResult:
score: float score: float
rank: int = 0 rank: int = 0
class Neo4jManager: class Neo4jManager:
"""Neo4j 图数据库管理器""" """Neo4j 图数据库管理器"""
@@ -962,9 +968,11 @@ class Neo4jManager:
return {"nodes": nodes, "relationships": relationships} return {"nodes": nodes, "relationships": relationships}
# 全局单例 # 全局单例
_neo4j_manager = None _neo4j_manager = None
def get_neo4j_manager() -> Neo4jManager: def get_neo4j_manager() -> Neo4jManager:
"""获取 Neo4j 管理器单例""" """获取 Neo4j 管理器单例"""
global _neo4j_manager global _neo4j_manager
@@ -972,6 +980,7 @@ def get_neo4j_manager() -> Neo4jManager:
_neo4j_manager = Neo4jManager() _neo4j_manager = Neo4jManager()
return _neo4j_manager return _neo4j_manager
def close_neo4j_manager() -> None: def close_neo4j_manager() -> None:
"""关闭 Neo4j 连接""" """关闭 Neo4j 连接"""
global _neo4j_manager global _neo4j_manager
@@ -980,6 +989,8 @@ def close_neo4j_manager() -> None:
_neo4j_manager = None _neo4j_manager = None
# 便捷函数 # 便捷函数
def sync_project_to_neo4j( def sync_project_to_neo4j(
project_id: str, project_name: str, entities: list[dict], relations: list[dict] project_id: str, project_name: str, entities: list[dict], relations: list[dict]
) -> None: ) -> None:
@@ -1033,6 +1044,7 @@ def sync_project_to_neo4j(
f"Synced project {project_id} to Neo4j: {len(entities)} entities, {len(relations)} relations" f"Synced project {project_id} to Neo4j: {len(entities)} entities, {len(relations)} relations"
) )
if __name__ == "__main__": if __name__ == "__main__":
# 测试代码 # 测试代码
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)

View File

@@ -29,6 +29,7 @@ import httpx
# Database path # Database path
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db") DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
class AlertSeverity(StrEnum): class AlertSeverity(StrEnum):
"""告警严重级别 P0-P3""" """告警严重级别 P0-P3"""
@@ -37,6 +38,7 @@ class AlertSeverity(StrEnum):
P2 = "p2" # 一般 - 部分功能受影响需要4小时内处理 P2 = "p2" # 一般 - 部分功能受影响需要4小时内处理
P3 = "p3" # 轻微 - 非核心功能问题24小时内处理 P3 = "p3" # 轻微 - 非核心功能问题24小时内处理
class AlertStatus(StrEnum): class AlertStatus(StrEnum):
"""告警状态""" """告警状态"""
@@ -45,6 +47,7 @@ class AlertStatus(StrEnum):
ACKNOWLEDGED = "acknowledged" # 已确认 ACKNOWLEDGED = "acknowledged" # 已确认
SUPPRESSED = "suppressed" # 已抑制 SUPPRESSED = "suppressed" # 已抑制
class AlertChannelType(StrEnum): class AlertChannelType(StrEnum):
"""告警渠道类型""" """告警渠道类型"""
@@ -57,6 +60,7 @@ class AlertChannelType(StrEnum):
SMS = "sms" SMS = "sms"
WEBHOOK = "webhook" WEBHOOK = "webhook"
class AlertRuleType(StrEnum): class AlertRuleType(StrEnum):
"""告警规则类型""" """告警规则类型"""
@@ -65,6 +69,7 @@ class AlertRuleType(StrEnum):
PREDICTIVE = "predictive" # 预测性告警 PREDICTIVE = "predictive" # 预测性告警
COMPOSITE = "composite" # 复合告警 COMPOSITE = "composite" # 复合告警
class ResourceType(StrEnum): class ResourceType(StrEnum):
"""资源类型""" """资源类型"""
@@ -77,6 +82,7 @@ class ResourceType(StrEnum):
CACHE = "cache" CACHE = "cache"
QUEUE = "queue" QUEUE = "queue"
class ScalingAction(StrEnum): class ScalingAction(StrEnum):
"""扩缩容动作""" """扩缩容动作"""
@@ -84,6 +90,7 @@ class ScalingAction(StrEnum):
SCALE_DOWN = "scale_down" # 缩容 SCALE_DOWN = "scale_down" # 缩容
MAINTAIN = "maintain" # 保持 MAINTAIN = "maintain" # 保持
class HealthStatus(StrEnum): class HealthStatus(StrEnum):
"""健康状态""" """健康状态"""
@@ -92,6 +99,7 @@ class HealthStatus(StrEnum):
UNHEALTHY = "unhealthy" UNHEALTHY = "unhealthy"
UNKNOWN = "unknown" UNKNOWN = "unknown"
class BackupStatus(StrEnum): class BackupStatus(StrEnum):
"""备份状态""" """备份状态"""
@@ -101,6 +109,7 @@ class BackupStatus(StrEnum):
FAILED = "failed" FAILED = "failed"
VERIFIED = "verified" VERIFIED = "verified"
@dataclass @dataclass
class AlertRule: class AlertRule:
"""告警规则""" """告警规则"""
@@ -124,6 +133,7 @@ class AlertRule:
updated_at: str updated_at: str
created_by: str created_by: str
@dataclass @dataclass
class AlertChannel: class AlertChannel:
"""告警渠道配置""" """告警渠道配置"""
@@ -141,6 +151,7 @@ class AlertChannel:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class Alert: class Alert:
"""告警实例""" """告警实例"""
@@ -164,6 +175,7 @@ class Alert:
notification_sent: dict[str, bool] # 渠道发送状态 notification_sent: dict[str, bool] # 渠道发送状态
suppression_count: int # 抑制计数 suppression_count: int # 抑制计数
@dataclass @dataclass
class AlertSuppressionRule: class AlertSuppressionRule:
"""告警抑制规则""" """告警抑制规则"""
@@ -177,6 +189,7 @@ class AlertSuppressionRule:
created_at: str created_at: str
expires_at: str | None expires_at: str | None
@dataclass @dataclass
class AlertGroup: class AlertGroup:
"""告警聚合组""" """告警聚合组"""
@@ -188,6 +201,7 @@ class AlertGroup:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class ResourceMetric: class ResourceMetric:
"""资源指标""" """资源指标"""
@@ -202,6 +216,7 @@ class ResourceMetric:
timestamp: str timestamp: str
metadata: dict metadata: dict
@dataclass @dataclass
class CapacityPlan: class CapacityPlan:
"""容量规划""" """容量规划"""
@@ -217,6 +232,7 @@ class CapacityPlan:
estimated_cost: float estimated_cost: float
created_at: str created_at: str
@dataclass @dataclass
class AutoScalingPolicy: class AutoScalingPolicy:
"""自动扩缩容策略""" """自动扩缩容策略"""
@@ -237,6 +253,7 @@ class AutoScalingPolicy:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class ScalingEvent: class ScalingEvent:
"""扩缩容事件""" """扩缩容事件"""
@@ -254,6 +271,7 @@ class ScalingEvent:
completed_at: str | None completed_at: str | None
error_message: str | None error_message: str | None
@dataclass @dataclass
class HealthCheck: class HealthCheck:
"""健康检查配置""" """健康检查配置"""
@@ -274,6 +292,7 @@ class HealthCheck:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class HealthCheckResult: class HealthCheckResult:
"""健康检查结果""" """健康检查结果"""
@@ -287,6 +306,7 @@ class HealthCheckResult:
details: dict details: dict
checked_at: str checked_at: str
@dataclass @dataclass
class FailoverConfig: class FailoverConfig:
"""故障转移配置""" """故障转移配置"""
@@ -304,6 +324,7 @@ class FailoverConfig:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class FailoverEvent: class FailoverEvent:
"""故障转移事件""" """故障转移事件"""
@@ -319,6 +340,7 @@ class FailoverEvent:
completed_at: str | None completed_at: str | None
rolled_back_at: str | None rolled_back_at: str | None
@dataclass @dataclass
class BackupJob: class BackupJob:
"""备份任务""" """备份任务"""
@@ -338,6 +360,7 @@ class BackupJob:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class BackupRecord: class BackupRecord:
"""备份记录""" """备份记录"""
@@ -354,6 +377,7 @@ class BackupRecord:
error_message: str | None error_message: str | None
storage_path: str storage_path: str
@dataclass @dataclass
class CostReport: class CostReport:
"""成本报告""" """成本报告"""
@@ -368,6 +392,7 @@ class CostReport:
anomalies: list[dict] # 异常检测 anomalies: list[dict] # 异常检测
created_at: str created_at: str
@dataclass @dataclass
class ResourceUtilization: class ResourceUtilization:
"""资源利用率""" """资源利用率"""
@@ -383,6 +408,7 @@ class ResourceUtilization:
report_date: str report_date: str
recommendations: list[str] recommendations: list[str]
@dataclass @dataclass
class IdleResource: class IdleResource:
"""闲置资源""" """闲置资源"""
@@ -399,6 +425,7 @@ class IdleResource:
recommendation: str recommendation: str
detected_at: str detected_at: str
@dataclass @dataclass
class CostOptimizationSuggestion: class CostOptimizationSuggestion:
"""成本优化建议""" """成本优化建议"""
@@ -418,6 +445,7 @@ class CostOptimizationSuggestion:
created_at: str created_at: str
applied_at: str | None applied_at: str | None
class OpsManager: class OpsManager:
"""运维与监控管理主类""" """运维与监控管理主类"""
@@ -3070,9 +3098,11 @@ class OpsManager:
applied_at=row["applied_at"], applied_at=row["applied_at"],
) )
# Singleton instance # Singleton instance
_ops_manager = None _ops_manager = None
def get_ops_manager() -> OpsManager: def get_ops_manager() -> OpsManager:
global _ops_manager global _ops_manager
if _ops_manager is None: if _ops_manager is None:

View File

@@ -9,6 +9,7 @@ from datetime import datetime
import oss2 import oss2
class OSSUploader: class OSSUploader:
def __init__(self): def __init__(self):
self.access_key = os.getenv("ALI_ACCESS_KEY") self.access_key = os.getenv("ALI_ACCESS_KEY")
@@ -40,9 +41,11 @@ class OSSUploader:
"""删除 OSS 对象""" """删除 OSS 对象"""
self.bucket.delete_object(object_name) self.bucket.delete_object(object_name)
# 单例 # 单例
_oss_uploader = None _oss_uploader = None
def get_oss_uploader() -> OSSUploader: def get_oss_uploader() -> OSSUploader:
global _oss_uploader global _oss_uploader
if _oss_uploader is None: if _oss_uploader is None:

View File

@@ -42,6 +42,7 @@ except ImportError:
# ==================== 数据模型 ==================== # ==================== 数据模型 ====================
@dataclass @dataclass
class CacheStats: class CacheStats:
"""缓存统计数据模型""" """缓存统计数据模型"""
@@ -58,6 +59,7 @@ class CacheStats:
if self.total_requests > 0: if self.total_requests > 0:
self.hit_rate = round(self.hits / self.total_requests, 4) self.hit_rate = round(self.hits / self.total_requests, 4)
@dataclass @dataclass
class CacheEntry: class CacheEntry:
"""缓存条目数据模型""" """缓存条目数据模型"""
@@ -70,6 +72,7 @@ class CacheEntry:
last_accessed: float = 0 last_accessed: float = 0
size_bytes: int = 0 size_bytes: int = 0
@dataclass @dataclass
class PerformanceMetric: class PerformanceMetric:
"""性能指标数据模型""" """性能指标数据模型"""
@@ -91,6 +94,7 @@ class PerformanceMetric:
"metadata": self.metadata, "metadata": self.metadata,
} }
@dataclass @dataclass
class TaskInfo: class TaskInfo:
"""任务信息数据模型""" """任务信息数据模型"""
@@ -122,6 +126,7 @@ class TaskInfo:
"max_retries": self.max_retries, "max_retries": self.max_retries,
} }
@dataclass @dataclass
class ShardInfo: class ShardInfo:
"""分片信息数据模型""" """分片信息数据模型"""
@@ -136,6 +141,7 @@ class ShardInfo:
# ==================== Redis 缓存层 ==================== # ==================== Redis 缓存层 ====================
class CacheManager: class CacheManager:
""" """
缓存管理器 缓存管理器
@@ -594,6 +600,7 @@ class CacheManager:
# ==================== 数据库分片 ==================== # ==================== 数据库分片 ====================
class DatabaseSharding: class DatabaseSharding:
""" """
数据库分片管理器 数据库分片管理器
@@ -895,6 +902,7 @@ class DatabaseSharding:
# ==================== 异步任务队列 ==================== # ==================== 异步任务队列 ====================
class TaskQueue: class TaskQueue:
""" """
异步任务队列管理器 异步任务队列管理器
@@ -1278,6 +1286,7 @@ class TaskQueue:
# ==================== 性能监控 ==================== # ==================== 性能监控 ====================
class PerformanceMonitor: class PerformanceMonitor:
""" """
性能监控器 性能监控器
@@ -1596,6 +1605,7 @@ class PerformanceMonitor:
# ==================== 性能装饰器 ==================== # ==================== 性能装饰器 ====================
def cached( def cached(
cache_manager: CacheManager, cache_manager: CacheManager,
key_prefix: str = "", key_prefix: str = "",
@@ -1640,6 +1650,7 @@ def cached(
return decorator return decorator
def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | None = None) -> None: def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | None = None) -> None:
""" """
性能监控装饰器 性能监控装饰器
@@ -1669,6 +1680,7 @@ def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | Non
# ==================== 性能管理器 ==================== # ==================== 性能管理器 ====================
class PerformanceManager: class PerformanceManager:
""" """
性能管理器 - 统一入口 性能管理器 - 统一入口
@@ -1730,9 +1742,11 @@ class PerformanceManager:
return stats return stats
# 单例模式 # 单例模式
_performance_manager = None _performance_manager = None
def get_performance_manager( def get_performance_manager(
db_path: str = "insightflow.db", redis_url: str | None = None, enable_sharding: bool = False db_path: str = "insightflow.db", redis_url: str | None = None, enable_sharding: bool = False
) -> PerformanceManager: ) -> PerformanceManager:

View File

@@ -30,6 +30,7 @@ try:
except ImportError: except ImportError:
WEBDAV_AVAILABLE = False WEBDAV_AVAILABLE = False
class PluginType(Enum): class PluginType(Enum):
"""插件类型""" """插件类型"""
@@ -41,6 +42,7 @@ class PluginType(Enum):
WEBDAV = "webdav" WEBDAV = "webdav"
CUSTOM = "custom" CUSTOM = "custom"
class PluginStatus(Enum): class PluginStatus(Enum):
"""插件状态""" """插件状态"""
@@ -49,6 +51,7 @@ class PluginStatus(Enum):
ERROR = "error" ERROR = "error"
PENDING = "pending" PENDING = "pending"
@dataclass @dataclass
class Plugin: class Plugin:
"""插件配置""" """插件配置"""
@@ -64,6 +67,7 @@ class Plugin:
last_used_at: str | None = None last_used_at: str | None = None
use_count: int = 0 use_count: int = 0
@dataclass @dataclass
class PluginConfig: class PluginConfig:
"""插件详细配置""" """插件详细配置"""
@@ -76,6 +80,7 @@ class PluginConfig:
created_at: str = "" created_at: str = ""
updated_at: str = "" updated_at: str = ""
@dataclass @dataclass
class BotSession: class BotSession:
"""机器人会话""" """机器人会话"""
@@ -93,6 +98,7 @@ class BotSession:
last_message_at: str | None = None last_message_at: str | None = None
message_count: int = 0 message_count: int = 0
@dataclass @dataclass
class WebhookEndpoint: class WebhookEndpoint:
"""Webhook 端点配置Zapier/Make集成""" """Webhook 端点配置Zapier/Make集成"""
@@ -111,6 +117,7 @@ class WebhookEndpoint:
last_triggered_at: str | None = None last_triggered_at: str | None = None
trigger_count: int = 0 trigger_count: int = 0
@dataclass @dataclass
class WebDAVSync: class WebDAVSync:
"""WebDAV 同步配置""" """WebDAV 同步配置"""
@@ -132,6 +139,7 @@ class WebDAVSync:
updated_at: str = "" updated_at: str = ""
sync_count: int = 0 sync_count: int = 0
@dataclass @dataclass
class ChromeExtensionToken: class ChromeExtensionToken:
"""Chrome 扩展令牌""" """Chrome 扩展令牌"""
@@ -148,6 +156,7 @@ class ChromeExtensionToken:
use_count: int = 0 use_count: int = 0
is_revoked: bool = False is_revoked: bool = False
class PluginManager: class PluginManager:
"""插件管理主类""" """插件管理主类"""
@@ -387,6 +396,7 @@ class PluginManager:
conn.commit() conn.commit()
conn.close() conn.close()
class ChromeExtensionHandler: class ChromeExtensionHandler:
"""Chrome 扩展处理器""" """Chrome 扩展处理器"""
@@ -590,6 +600,7 @@ class ChromeExtensionHandler:
"content_length": len(content), "content_length": len(content),
} }
class BotHandler: class BotHandler:
"""飞书/钉钉机器人处理器""" """飞书/钉钉机器人处理器"""
@@ -917,6 +928,7 @@ class BotHandler:
) )
return response.status_code == 200 return response.status_code == 200
class WebhookIntegration: class WebhookIntegration:
"""Zapier/Make Webhook 集成""" """Zapier/Make Webhook 集成"""
@@ -1139,6 +1151,7 @@ class WebhookIntegration:
"message": "Test event sent successfully" if success else "Failed to send test event", "message": "Test event sent successfully" if success else "Failed to send test event",
} }
class WebDAVSyncManager: class WebDAVSyncManager:
"""WebDAV 同步管理""" """WebDAV 同步管理"""
@@ -1399,9 +1412,11 @@ class WebDAVSyncManager:
return {"success": False, "error": str(e)} return {"success": False, "error": str(e)}
# Singleton instance # Singleton instance
_plugin_manager = None _plugin_manager = None
def get_plugin_manager(db_manager=None) -> None: def get_plugin_manager(db_manager=None) -> None:
"""获取 PluginManager 单例""" """获取 PluginManager 单例"""
global _plugin_manager global _plugin_manager

View File

@@ -12,6 +12,7 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from functools import wraps from functools import wraps
@dataclass @dataclass
class RateLimitConfig: class RateLimitConfig:
"""限流配置""" """限流配置"""
@@ -20,6 +21,7 @@ class RateLimitConfig:
burst_size: int = 10 # 突发请求数 burst_size: int = 10 # 突发请求数
window_size: int = 60 # 窗口大小(秒) window_size: int = 60 # 窗口大小(秒)
@dataclass @dataclass
class RateLimitInfo: class RateLimitInfo:
"""限流信息""" """限流信息"""
@@ -29,6 +31,7 @@ class RateLimitInfo:
reset_time: int # 重置时间戳 reset_time: int # 重置时间戳
retry_after: int # 需要等待的秒数 retry_after: int # 需要等待的秒数
class SlidingWindowCounter: class SlidingWindowCounter:
"""滑动窗口计数器""" """滑动窗口计数器"""
@@ -60,6 +63,7 @@ class SlidingWindowCounter:
for k in old_keys: for k in old_keys:
self.requests.pop(k, None) self.requests.pop(k, None)
class RateLimiter: class RateLimiter:
"""API 限流器""" """API 限流器"""
@@ -155,9 +159,11 @@ class RateLimiter:
self.counters.clear() self.counters.clear()
self.configs.clear() self.configs.clear()
# 全局限流器实例 # 全局限流器实例
_rate_limiter: RateLimiter | None = None _rate_limiter: RateLimiter | None = None
def get_rate_limiter() -> RateLimiter: def get_rate_limiter() -> RateLimiter:
"""获取限流器实例""" """获取限流器实例"""
global _rate_limiter global _rate_limiter
@@ -167,6 +173,7 @@ def get_rate_limiter() -> RateLimiter:
# 限流装饰器(用于函数级别限流) # 限流装饰器(用于函数级别限流)
def rate_limit(requests_per_minute: int = 60, key_func: Callable | None = None) -> None: def rate_limit(requests_per_minute: int = 60, key_func: Callable | None = None) -> None:
""" """
限流装饰器 限流装饰器
@@ -209,5 +216,6 @@ def rate_limit(requests_per_minute: int = 60, key_func: Callable | None = None)
return decorator return decorator
class RateLimitExceeded(Exception): class RateLimitExceeded(Exception):
"""限流异常""" """限流异常"""

View File

@@ -19,6 +19,7 @@ from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from enum import Enum from enum import Enum
class SearchOperator(Enum): class SearchOperator(Enum):
"""搜索操作符""" """搜索操作符"""
@@ -26,6 +27,7 @@ class SearchOperator(Enum):
OR = "OR" OR = "OR"
NOT = "NOT" NOT = "NOT"
# 尝试导入 sentence-transformers 用于语义搜索 # 尝试导入 sentence-transformers 用于语义搜索
try: try:
from sentence_transformers import SentenceTransformer from sentence_transformers import SentenceTransformer
@@ -37,6 +39,7 @@ except ImportError:
# ==================== 数据模型 ==================== # ==================== 数据模型 ====================
@dataclass @dataclass
class SearchResult: class SearchResult:
"""搜索结果数据模型""" """搜索结果数据模型"""
@@ -60,6 +63,7 @@ class SearchResult:
"metadata": self.metadata, "metadata": self.metadata,
} }
@dataclass @dataclass
class SemanticSearchResult: class SemanticSearchResult:
"""语义搜索结果数据模型""" """语义搜索结果数据模型"""
@@ -85,6 +89,7 @@ class SemanticSearchResult:
result["embedding_dim"] = len(self.embedding) result["embedding_dim"] = len(self.embedding)
return result return result
@dataclass @dataclass
class EntityPath: class EntityPath:
"""实体关系路径数据模型""" """实体关系路径数据模型"""
@@ -114,6 +119,7 @@ class EntityPath:
"path_description": self.path_description, "path_description": self.path_description,
} }
@dataclass @dataclass
class KnowledgeGap: class KnowledgeGap:
"""知识缺口数据模型""" """知识缺口数据模型"""
@@ -141,6 +147,7 @@ class KnowledgeGap:
"metadata": self.metadata, "metadata": self.metadata,
} }
@dataclass @dataclass
class SearchIndex: class SearchIndex:
"""搜索索引数据模型""" """搜索索引数据模型"""
@@ -154,6 +161,7 @@ class SearchIndex:
created_at: str created_at: str
updated_at: str updated_at: str
@dataclass @dataclass
class TextEmbedding: class TextEmbedding:
"""文本 Embedding 数据模型""" """文本 Embedding 数据模型"""
@@ -168,6 +176,7 @@ class TextEmbedding:
# ==================== 全文搜索 ==================== # ==================== 全文搜索 ====================
class FullTextSearch: class FullTextSearch:
""" """
全文搜索模块 全文搜索模块
@@ -778,6 +787,7 @@ class FullTextSearch:
# ==================== 语义搜索 ==================== # ==================== 语义搜索 ====================
class SemanticSearch: class SemanticSearch:
""" """
语义搜索模块 语义搜索模块
@@ -1140,6 +1150,7 @@ class SemanticSearch:
# ==================== 实体关系路径发现 ==================== # ==================== 实体关系路径发现 ====================
class EntityPathDiscovery: class EntityPathDiscovery:
""" """
实体关系路径发现模块 实体关系路径发现模块
@@ -1611,6 +1622,7 @@ class EntityPathDiscovery:
# ==================== 知识缺口识别 ==================== # ==================== 知识缺口识别 ====================
class KnowledgeGapDetection: class KnowledgeGapDetection:
""" """
知识缺口识别模块 知识缺口识别模块
@@ -2015,6 +2027,7 @@ class KnowledgeGapDetection:
# ==================== 搜索管理器 ==================== # ==================== 搜索管理器 ====================
class SearchManager: class SearchManager:
""" """
搜索管理器 - 统一入口 搜索管理器 - 统一入口
@@ -2187,9 +2200,11 @@ class SearchManager:
"semantic_search_available": self.semantic_search.is_available(), "semantic_search_available": self.semantic_search.is_available(),
} }
# 单例模式 # 单例模式
_search_manager = None _search_manager = None
def get_search_manager(db_path: str = "insightflow.db") -> SearchManager: def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
"""获取搜索管理器单例""" """获取搜索管理器单例"""
global _search_manager global _search_manager
@@ -2198,6 +2213,8 @@ def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
return _search_manager return _search_manager
# 便捷函数 # 便捷函数
def fulltext_search( def fulltext_search(
query: str, project_id: str | None = None, limit: int = 20 query: str, project_id: str | None = None, limit: int = 20
) -> list[SearchResult]: ) -> list[SearchResult]:
@@ -2205,6 +2222,7 @@ def fulltext_search(
manager = get_search_manager() manager = get_search_manager()
return manager.fulltext_search.search(query, project_id, limit=limit) return manager.fulltext_search.search(query, project_id, limit=limit)
def semantic_search( def semantic_search(
query: str, project_id: str | None = None, top_k: int = 10 query: str, project_id: str | None = None, top_k: int = 10
) -> list[SemanticSearchResult]: ) -> list[SemanticSearchResult]:
@@ -2212,11 +2230,13 @@ def semantic_search(
manager = get_search_manager() manager = get_search_manager()
return manager.semantic_search.search(query, project_id, top_k=top_k) 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: def find_entity_path(source_id: str, target_id: str, max_depth: int = 5) -> EntityPath | None:
"""查找实体路径便捷函数""" """查找实体路径便捷函数"""
manager = get_search_manager() manager = get_search_manager()
return manager.path_discovery.find_shortest_path(source_id, target_id, max_depth) return manager.path_discovery.find_shortest_path(source_id, target_id, max_depth)
def detect_knowledge_gaps(project_id: str) -> list[KnowledgeGap]: def detect_knowledge_gaps(project_id: str) -> list[KnowledgeGap]:
"""知识缺口检测便捷函数""" """知识缺口检测便捷函数"""
manager = get_search_manager() manager = get_search_manager()

View File

@@ -25,6 +25,7 @@ except ImportError:
CRYPTO_AVAILABLE = False CRYPTO_AVAILABLE = False
print("Warning: cryptography not available, encryption features disabled") print("Warning: cryptography not available, encryption features disabled")
class AuditActionType(Enum): class AuditActionType(Enum):
"""审计动作类型""" """审计动作类型"""
@@ -47,6 +48,7 @@ class AuditActionType(Enum):
WEBHOOK_SEND = "webhook_send" WEBHOOK_SEND = "webhook_send"
BOT_MESSAGE = "bot_message" BOT_MESSAGE = "bot_message"
class DataSensitivityLevel(Enum): class DataSensitivityLevel(Enum):
"""数据敏感度级别""" """数据敏感度级别"""
@@ -55,6 +57,7 @@ class DataSensitivityLevel(Enum):
CONFIDENTIAL = "confidential" # 机密 CONFIDENTIAL = "confidential" # 机密
SECRET = "secret" # 绝密 SECRET = "secret" # 绝密
class MaskingRuleType(Enum): class MaskingRuleType(Enum):
"""脱敏规则类型""" """脱敏规则类型"""
@@ -66,6 +69,7 @@ class MaskingRuleType(Enum):
ADDRESS = "address" # 地址 ADDRESS = "address" # 地址
CUSTOM = "custom" # 自定义 CUSTOM = "custom" # 自定义
@dataclass @dataclass
class AuditLog: class AuditLog:
"""审计日志条目""" """审计日志条目"""
@@ -87,6 +91,7 @@ class AuditLog:
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return asdict(self) return asdict(self)
@dataclass @dataclass
class EncryptionConfig: class EncryptionConfig:
"""加密配置""" """加密配置"""
@@ -104,6 +109,7 @@ class EncryptionConfig:
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return asdict(self) return asdict(self)
@dataclass @dataclass
class MaskingRule: class MaskingRule:
"""脱敏规则""" """脱敏规则"""
@@ -123,6 +129,7 @@ class MaskingRule:
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return asdict(self) return asdict(self)
@dataclass @dataclass
class DataAccessPolicy: class DataAccessPolicy:
"""数据访问策略""" """数据访问策略"""
@@ -144,6 +151,7 @@ class DataAccessPolicy:
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return asdict(self) return asdict(self)
@dataclass @dataclass
class AccessRequest: class AccessRequest:
"""访问请求(用于需要审批的访问)""" """访问请求(用于需要审批的访问)"""
@@ -161,6 +169,7 @@ class AccessRequest:
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return asdict(self) return asdict(self)
class SecurityManager: class SecurityManager:
"""安全管理器""" """安全管理器"""
@@ -1231,9 +1240,11 @@ class SecurityManager:
created_at=row[8], created_at=row[8],
) )
# 全局安全管理器实例 # 全局安全管理器实例
_security_manager = None _security_manager = None
def get_security_manager(db_path: str = "insightflow.db") -> SecurityManager: def get_security_manager(db_path: str = "insightflow.db") -> SecurityManager:
"""获取安全管理器实例""" """获取安全管理器实例"""
global _security_manager global _security_manager

View File

@@ -21,6 +21,7 @@ from typing import Any
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SubscriptionStatus(StrEnum): class SubscriptionStatus(StrEnum):
"""订阅状态""" """订阅状态"""
@@ -31,6 +32,7 @@ class SubscriptionStatus(StrEnum):
TRIAL = "trial" # 试用中 TRIAL = "trial" # 试用中
PENDING = "pending" # 待支付 PENDING = "pending" # 待支付
class PaymentProvider(StrEnum): class PaymentProvider(StrEnum):
"""支付提供商""" """支付提供商"""
@@ -39,6 +41,7 @@ class PaymentProvider(StrEnum):
WECHAT = "wechat" # 微信支付 WECHAT = "wechat" # 微信支付
BANK_TRANSFER = "bank_transfer" # 银行转账 BANK_TRANSFER = "bank_transfer" # 银行转账
class PaymentStatus(StrEnum): class PaymentStatus(StrEnum):
"""支付状态""" """支付状态"""
@@ -49,6 +52,7 @@ class PaymentStatus(StrEnum):
REFUNDED = "refunded" # 已退款 REFUNDED = "refunded" # 已退款
PARTIAL_REFUNDED = "partial_refunded" # 部分退款 PARTIAL_REFUNDED = "partial_refunded" # 部分退款
class InvoiceStatus(StrEnum): class InvoiceStatus(StrEnum):
"""发票状态""" """发票状态"""
@@ -59,6 +63,7 @@ class InvoiceStatus(StrEnum):
VOID = "void" # 作废 VOID = "void" # 作废
CREDIT_NOTE = "credit_note" # 贷项通知单 CREDIT_NOTE = "credit_note" # 贷项通知单
class RefundStatus(StrEnum): class RefundStatus(StrEnum):
"""退款状态""" """退款状态"""
@@ -68,6 +73,7 @@ class RefundStatus(StrEnum):
COMPLETED = "completed" # 已完成 COMPLETED = "completed" # 已完成
FAILED = "failed" # 失败 FAILED = "failed" # 失败
@dataclass @dataclass
class SubscriptionPlan: class SubscriptionPlan:
"""订阅计划数据类""" """订阅计划数据类"""
@@ -86,6 +92,7 @@ class SubscriptionPlan:
updated_at: datetime updated_at: datetime
metadata: dict[str, Any] metadata: dict[str, Any]
@dataclass @dataclass
class Subscription: class Subscription:
"""订阅数据类""" """订阅数据类"""
@@ -106,6 +113,7 @@ class Subscription:
updated_at: datetime updated_at: datetime
metadata: dict[str, Any] metadata: dict[str, Any]
@dataclass @dataclass
class UsageRecord: class UsageRecord:
"""用量记录数据类""" """用量记录数据类"""
@@ -120,6 +128,7 @@ class UsageRecord:
description: str | None description: str | None
metadata: dict[str, Any] metadata: dict[str, Any]
@dataclass @dataclass
class Payment: class Payment:
"""支付记录数据类""" """支付记录数据类"""
@@ -141,6 +150,7 @@ class Payment:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class Invoice: class Invoice:
"""发票数据类""" """发票数据类"""
@@ -164,6 +174,7 @@ class Invoice:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class Refund: class Refund:
"""退款数据类""" """退款数据类"""
@@ -186,6 +197,7 @@ class Refund:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class BillingHistory: class BillingHistory:
"""账单历史数据类""" """账单历史数据类"""
@@ -201,6 +213,7 @@ class BillingHistory:
created_at: datetime created_at: datetime
metadata: dict[str, Any] metadata: dict[str, Any]
class SubscriptionManager: class SubscriptionManager:
"""订阅与计费管理器""" """订阅与计费管理器"""
@@ -2187,9 +2200,11 @@ class SubscriptionManager:
metadata=json.loads(row["metadata"] or "{}"), metadata=json.loads(row["metadata"] or "{}"),
) )
# 全局订阅管理器实例 # 全局订阅管理器实例
subscription_manager = None subscription_manager = None
def get_subscription_manager(db_path: str = "insightflow.db") -> SubscriptionManager: def get_subscription_manager(db_path: str = "insightflow.db") -> SubscriptionManager:
"""获取订阅管理器实例(单例模式)""" """获取订阅管理器实例(单例模式)"""
global subscription_manager global subscription_manager

View File

@@ -23,6 +23,7 @@ from typing import Any
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TenantLimits: class TenantLimits:
"""租户资源限制常量""" """租户资源限制常量"""
@@ -42,6 +43,7 @@ class TenantLimits:
UNLIMITED = -1 UNLIMITED = -1
class TenantStatus(StrEnum): class TenantStatus(StrEnum):
"""租户状态""" """租户状态"""
@@ -51,6 +53,7 @@ class TenantStatus(StrEnum):
EXPIRED = "expired" # 过期 EXPIRED = "expired" # 过期
PENDING = "pending" # 待激活 PENDING = "pending" # 待激活
class TenantTier(StrEnum): class TenantTier(StrEnum):
"""租户订阅层级""" """租户订阅层级"""
@@ -58,6 +61,7 @@ class TenantTier(StrEnum):
PRO = "pro" # 专业版 PRO = "pro" # 专业版
ENTERPRISE = "enterprise" # 企业版 ENTERPRISE = "enterprise" # 企业版
class TenantRole(StrEnum): class TenantRole(StrEnum):
"""租户角色""" """租户角色"""
@@ -66,6 +70,7 @@ class TenantRole(StrEnum):
MEMBER = "member" # 成员 MEMBER = "member" # 成员
VIEWER = "viewer" # 查看者 VIEWER = "viewer" # 查看者
class DomainStatus(StrEnum): class DomainStatus(StrEnum):
"""域名状态""" """域名状态"""
@@ -74,6 +79,7 @@ class DomainStatus(StrEnum):
FAILED = "failed" # 验证失败 FAILED = "failed" # 验证失败
EXPIRED = "expired" # 已过期 EXPIRED = "expired" # 已过期
@dataclass @dataclass
class Tenant: class Tenant:
"""租户数据类""" """租户数据类"""
@@ -92,6 +98,7 @@ class Tenant:
resource_limits: dict[str, Any] # 资源限制 resource_limits: dict[str, Any] # 资源限制
metadata: dict[str, Any] # 元数据 metadata: dict[str, Any] # 元数据
@dataclass @dataclass
class TenantDomain: class TenantDomain:
"""租户域名数据类""" """租户域名数据类"""
@@ -109,6 +116,7 @@ class TenantDomain:
ssl_enabled: bool # SSL 是否启用 ssl_enabled: bool # SSL 是否启用
ssl_expires_at: datetime | None ssl_expires_at: datetime | None
@dataclass @dataclass
class TenantBranding: class TenantBranding:
"""租户品牌配置数据类""" """租户品牌配置数据类"""
@@ -126,6 +134,7 @@ class TenantBranding:
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
@dataclass @dataclass
class TenantMember: class TenantMember:
"""租户成员数据类""" """租户成员数据类"""
@@ -142,6 +151,7 @@ class TenantMember:
last_active_at: datetime | None last_active_at: datetime | None
status: str # active/pending/suspended status: str # active/pending/suspended
@dataclass @dataclass
class TenantPermission: class TenantPermission:
"""租户权限定义数据类""" """租户权限定义数据类"""
@@ -156,6 +166,7 @@ class TenantPermission:
conditions: dict | None # 条件限制 conditions: dict | None # 条件限制
created_at: datetime created_at: datetime
class TenantManager: class TenantManager:
"""租户管理器 - 多租户 SaaS 架构核心""" """租户管理器 - 多租户 SaaS 架构核心"""
@@ -1601,6 +1612,7 @@ class TenantManager:
# ==================== 租户上下文管理 ==================== # ==================== 租户上下文管理 ====================
class TenantContext: class TenantContext:
"""租户上下文管理器 - 用于请求级别的租户隔离""" """租户上下文管理器 - 用于请求级别的租户隔离"""
@@ -1633,9 +1645,11 @@ class TenantContext:
cls._current_tenant_id = None cls._current_tenant_id = None
cls._current_user_id = None cls._current_user_id = None
# 全局租户管理器实例 # 全局租户管理器实例
tenant_manager = None tenant_manager = None
def get_tenant_manager(db_path: str = "insightflow.db") -> TenantManager: def get_tenant_manager(db_path: str = "insightflow.db") -> TenantManager:
"""获取租户管理器实例(单例模式)""" """获取租户管理器实例(单例模式)"""
global tenant_manager global tenant_manager

View File

@@ -20,6 +20,7 @@ from search_manager import (
# 添加 backend 到路径 # 添加 backend 到路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def test_fulltext_search(): def test_fulltext_search():
"""测试全文搜索""" """测试全文搜索"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -62,6 +63,7 @@ def test_fulltext_search():
print("\n✓ 全文搜索测试完成") print("\n✓ 全文搜索测试完成")
return True return True
def test_semantic_search(): def test_semantic_search():
"""测试语义搜索""" """测试语义搜索"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -97,6 +99,7 @@ def test_semantic_search():
print("\n✓ 语义搜索测试完成") print("\n✓ 语义搜索测试完成")
return True return True
def test_entity_path_discovery(): def test_entity_path_discovery():
"""测试实体路径发现""" """测试实体路径发现"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -115,6 +118,7 @@ def test_entity_path_discovery():
print("\n✓ 实体路径发现测试完成") print("\n✓ 实体路径发现测试完成")
return True return True
def test_knowledge_gap_detection(): def test_knowledge_gap_detection():
"""测试知识缺口识别""" """测试知识缺口识别"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -133,6 +137,7 @@ def test_knowledge_gap_detection():
print("\n✓ 知识缺口识别测试完成") print("\n✓ 知识缺口识别测试完成")
return True return True
def test_cache_manager(): def test_cache_manager():
"""测试缓存管理器""" """测试缓存管理器"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -180,6 +185,7 @@ def test_cache_manager():
print("\n✓ 缓存管理器测试完成") print("\n✓ 缓存管理器测试完成")
return True return True
def test_task_queue(): def test_task_queue():
"""测试任务队列""" """测试任务队列"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -220,6 +226,7 @@ def test_task_queue():
print("\n✓ 任务队列测试完成") print("\n✓ 任务队列测试完成")
return True return True
def test_performance_monitor(): def test_performance_monitor():
"""测试性能监控""" """测试性能监控"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -266,6 +273,7 @@ def test_performance_monitor():
print("\n✓ 性能监控测试完成") print("\n✓ 性能监控测试完成")
return True return True
def test_search_manager(): def test_search_manager():
"""测试搜索管理器""" """测试搜索管理器"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -286,6 +294,7 @@ def test_search_manager():
print("\n✓ 搜索管理器测试完成") print("\n✓ 搜索管理器测试完成")
return True return True
def test_performance_manager(): def test_performance_manager():
"""测试性能管理器""" """测试性能管理器"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -310,6 +319,7 @@ def test_performance_manager():
print("\n✓ 性能管理器测试完成") print("\n✓ 性能管理器测试完成")
return True return True
def run_all_tests(): def run_all_tests():
"""运行所有测试""" """运行所有测试"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -396,6 +406,7 @@ def run_all_tests():
return passed == total return passed == total
if __name__ == "__main__": if __name__ == "__main__":
success = run_all_tests() success = run_all_tests()
sys.exit(0 if success else 1) sys.exit(0 if success else 1)

View File

@@ -17,6 +17,7 @@ from tenant_manager import get_tenant_manager
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def test_tenant_management(): def test_tenant_management():
"""测试租户管理功能""" """测试租户管理功能"""
print("=" * 60) print("=" * 60)
@@ -64,6 +65,7 @@ def test_tenant_management():
return tenant.id return tenant.id
def test_domain_management(tenant_id: str): def test_domain_management(tenant_id: str):
"""测试域名管理功能""" """测试域名管理功能"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -109,6 +111,7 @@ def test_domain_management(tenant_id: str):
return domain.id return domain.id
def test_branding_management(tenant_id: str): def test_branding_management(tenant_id: str):
"""测试品牌白标功能""" """测试品牌白标功能"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -148,6 +151,7 @@ def test_branding_management(tenant_id: str):
return branding.id return branding.id
def test_member_management(tenant_id: str): def test_member_management(tenant_id: str):
"""测试成员管理功能""" """测试成员管理功能"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -202,6 +206,7 @@ def test_member_management(tenant_id: str):
return member1.id, member2.id return member1.id, member2.id
def test_usage_tracking(tenant_id: str): def test_usage_tracking(tenant_id: str):
"""测试资源使用统计功能""" """测试资源使用统计功能"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -243,6 +248,7 @@ def test_usage_tracking(tenant_id: str):
return stats return stats
def cleanup(tenant_id: str, domain_id: str, member_ids: list): def cleanup(tenant_id: str, domain_id: str, member_ids: list):
"""清理测试数据""" """清理测试数据"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -266,6 +272,7 @@ def cleanup(tenant_id: str, domain_id: str, member_ids: list):
manager.delete_tenant(tenant_id) manager.delete_tenant(tenant_id)
print(f"✅ 租户已删除: {tenant_id}") print(f"✅ 租户已删除: {tenant_id}")
def main(): def main():
"""主测试函数""" """主测试函数"""
print("\n" + "=" * 60) print("\n" + "=" * 60)
@@ -303,5 +310,6 @@ def main():
except Exception as e: except Exception as e:
print(f"⚠️ 清理失败: {e}") print(f"⚠️ 清理失败: {e}")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -11,6 +11,7 @@ from subscription_manager import PaymentProvider, SubscriptionManager
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def test_subscription_manager(): def test_subscription_manager():
"""测试订阅管理器""" """测试订阅管理器"""
print("=" * 60) print("=" * 60)
@@ -223,6 +224,7 @@ def test_subscription_manager():
os.remove(db_path) os.remove(db_path)
print(f"\n清理临时数据库: {db_path}") print(f"\n清理临时数据库: {db_path}")
if __name__ == "__main__": if __name__ == "__main__":
try: try:
test_subscription_manager() test_subscription_manager()

View File

@@ -13,6 +13,7 @@ from ai_manager import ModelType, PredictionType, get_ai_manager
# Add backend directory to path # Add backend directory to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def test_custom_model(): def test_custom_model():
"""测试自定义模型功能""" """测试自定义模型功能"""
print("\n=== 测试自定义模型 ===") print("\n=== 测试自定义模型 ===")
@@ -87,6 +88,7 @@ def test_custom_model():
return model.id return model.id
async def test_train_and_predict(model_id: str): async def test_train_and_predict(model_id: str):
"""测试训练和预测""" """测试训练和预测"""
print("\n=== 测试模型训练和预测 ===") print("\n=== 测试模型训练和预测 ===")
@@ -113,6 +115,7 @@ async def test_train_and_predict(model_id: str):
except Exception as e: except Exception as e:
print(f" 预测失败: {e}") print(f" 预测失败: {e}")
def test_prediction_models(): def test_prediction_models():
"""测试预测模型""" """测试预测模型"""
print("\n=== 测试预测模型 ===") print("\n=== 测试预测模型 ===")
@@ -154,6 +157,7 @@ def test_prediction_models():
return trend_model.id, anomaly_model.id return trend_model.id, anomaly_model.id
async def test_predictions(trend_model_id: str, anomaly_model_id: str): async def test_predictions(trend_model_id: str, anomaly_model_id: str):
"""测试预测功能""" """测试预测功能"""
print("\n=== 测试预测功能 ===") print("\n=== 测试预测功能 ===")
@@ -188,6 +192,7 @@ async def test_predictions(trend_model_id: str, anomaly_model_id: str):
) )
print(f" 检测结果: {anomaly_result.prediction_data}") print(f" 检测结果: {anomaly_result.prediction_data}")
def test_kg_rag(): def test_kg_rag():
"""测试知识图谱 RAG""" """测试知识图谱 RAG"""
print("\n=== 测试知识图谱 RAG ===") print("\n=== 测试知识图谱 RAG ===")
@@ -217,6 +222,7 @@ def test_kg_rag():
return rag.id return rag.id
async def test_kg_rag_query(rag_id: str): async def test_kg_rag_query(rag_id: str):
"""测试 RAG 查询""" """测试 RAG 查询"""
print("\n=== 测试知识图谱 RAG 查询 ===") print("\n=== 测试知识图谱 RAG 查询 ===")
@@ -287,6 +293,7 @@ async def test_kg_rag_query(rag_id: str):
except Exception as e: except Exception as e:
print(f" 查询失败: {e}") print(f" 查询失败: {e}")
async def test_smart_summary(): async def test_smart_summary():
"""测试智能摘要""" """测试智能摘要"""
print("\n=== 测试智能摘要 ===") print("\n=== 测试智能摘要 ===")
@@ -334,6 +341,7 @@ async def test_smart_summary():
except Exception as e: except Exception as e:
print(f" 生成失败: {e}") print(f" 生成失败: {e}")
async def main(): async def main():
"""主测试函数""" """主测试函数"""
print("=" * 60) print("=" * 60)

View File

@@ -32,6 +32,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
if backend_dir not in sys.path: if backend_dir not in sys.path:
sys.path.insert(0, backend_dir) sys.path.insert(0, backend_dir)
class TestGrowthManager: class TestGrowthManager:
"""测试 Growth Manager 功能""" """测试 Growth Manager 功能"""
@@ -734,6 +735,7 @@ class TestGrowthManager:
print("✨ 测试完成!") print("✨ 测试完成!")
print("=" * 60) print("=" * 60)
async def main(): async def main():
"""主函数""" """主函数"""
tester = TestGrowthManager() tester = TestGrowthManager()

View File

@@ -29,6 +29,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
if backend_dir not in sys.path: if backend_dir not in sys.path:
sys.path.insert(0, backend_dir) sys.path.insert(0, backend_dir)
class TestDeveloperEcosystem: class TestDeveloperEcosystem:
"""开发者生态系统测试类""" """开发者生态系统测试类"""
@@ -687,10 +688,12 @@ console.log('Upload complete:', result.id);
print("=" * 60) print("=" * 60)
def main(): def main():
"""主函数""" """主函数"""
test = TestDeveloperEcosystem() test = TestDeveloperEcosystem()
test.run_all_tests() test.run_all_tests()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -30,6 +30,7 @@ backend_dir = os.path.dirname(os.path.abspath(__file__))
if backend_dir not in sys.path: if backend_dir not in sys.path:
sys.path.insert(0, backend_dir) sys.path.insert(0, backend_dir)
class TestOpsManager: class TestOpsManager:
"""测试运维与监控管理器""" """测试运维与监控管理器"""
@@ -721,10 +722,12 @@ class TestOpsManager:
print("=" * 60) print("=" * 60)
def main(): def main():
"""主函数""" """主函数"""
test = TestOpsManager() test = TestOpsManager()
test.run_all_tests() test.run_all_tests()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -8,6 +8,7 @@ import time
from datetime import datetime from datetime import datetime
from typing import Any from typing import Any
class TingwuClient: class TingwuClient:
def __init__(self): def __init__(self):
self.access_key = os.getenv("ALI_ACCESS_KEY", "") self.access_key = os.getenv("ALI_ACCESS_KEY", "")

View File

@@ -38,6 +38,7 @@ DEFAULT_RETRY_DELAY = 5 # 默认重试延迟(秒)
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class WorkflowStatus(Enum): class WorkflowStatus(Enum):
"""工作流状态""" """工作流状态"""
@@ -46,6 +47,7 @@ class WorkflowStatus(Enum):
ERROR = "error" ERROR = "error"
COMPLETED = "completed" COMPLETED = "completed"
class WorkflowType(Enum): class WorkflowType(Enum):
"""工作流类型""" """工作流类型"""
@@ -55,6 +57,7 @@ class WorkflowType(Enum):
SCHEDULED_REPORT = "scheduled_report" # 定时报告 SCHEDULED_REPORT = "scheduled_report" # 定时报告
CUSTOM = "custom" # 自定义工作流 CUSTOM = "custom" # 自定义工作流
class WebhookType(Enum): class WebhookType(Enum):
"""Webhook 类型""" """Webhook 类型"""
@@ -63,6 +66,7 @@ class WebhookType(Enum):
SLACK = "slack" SLACK = "slack"
CUSTOM = "custom" CUSTOM = "custom"
class TaskStatus(Enum): class TaskStatus(Enum):
"""任务执行状态""" """任务执行状态"""
@@ -72,6 +76,7 @@ class TaskStatus(Enum):
FAILED = "failed" FAILED = "failed"
CANCELLED = "cancelled" CANCELLED = "cancelled"
@dataclass @dataclass
class WorkflowTask: class WorkflowTask:
"""工作流任务定义""" """工作流任务定义"""
@@ -95,6 +100,7 @@ class WorkflowTask:
if not self.updated_at: if not self.updated_at:
self.updated_at = self.created_at self.updated_at = self.created_at
@dataclass @dataclass
class WebhookConfig: class WebhookConfig:
"""Webhook 配置""" """Webhook 配置"""
@@ -119,6 +125,7 @@ class WebhookConfig:
if not self.updated_at: if not self.updated_at:
self.updated_at = self.created_at self.updated_at = self.created_at
@dataclass @dataclass
class Workflow: class Workflow:
"""工作流定义""" """工作流定义"""
@@ -148,6 +155,7 @@ class Workflow:
if not self.updated_at: if not self.updated_at:
self.updated_at = self.created_at self.updated_at = self.created_at
@dataclass @dataclass
class WorkflowLog: class WorkflowLog:
"""工作流执行日志""" """工作流执行日志"""
@@ -168,6 +176,7 @@ class WorkflowLog:
if not self.created_at: if not self.created_at:
self.created_at = datetime.now().isoformat() self.created_at = datetime.now().isoformat()
class WebhookNotifier: class WebhookNotifier:
"""Webhook 通知器 - 支持飞书、钉钉、Slack""" """Webhook 通知器 - 支持飞书、钉钉、Slack"""
@@ -323,6 +332,7 @@ class WebhookNotifier:
"""关闭 HTTP 客户端""" """关闭 HTTP 客户端"""
await self.http_client.aclose() await self.http_client.aclose()
class WorkflowManager: class WorkflowManager:
"""工作流管理器 - 核心管理类""" """工作流管理器 - 核心管理类"""
@@ -1493,9 +1503,11 @@ class WorkflowManager:
] ]
} }
# Singleton instance # Singleton instance
_workflow_manager = None _workflow_manager = None
def get_workflow_manager(db_manager=None) -> WorkflowManager: def get_workflow_manager(db_manager=None) -> WorkflowManager:
"""获取 WorkflowManager 单例""" """获取 WorkflowManager 单例"""
global _workflow_manager global _workflow_manager