fix: auto-fix code issues (cron)

- 修复未定义名称 (F821): 添加缺失的导入
  - ExportEntity, ExportRelation, ExportTranscript
  - WorkflowManager, PluginManager, OpsManager
  - urllib.parse
- 修复裸异常捕获: except: → except Exception:
- 删除 __pycache__ 缓存文件
- 格式化代码 (PEP8)

自动化修复: 23个问题
剩余需手动处理: 104个行长度问题 (E501)
This commit is contained in:
AutoFix Bot
2026-03-01 21:14:19 +08:00
parent e46c938b40
commit cdf0e80851
53 changed files with 358 additions and 17 deletions

192
auto_fix_code.py Normal file
View File

@@ -0,0 +1,192 @@
#!/usr/bin/env python3
"""
InsightFlow 代码自动修复脚本 - 增强版
自动修复代码中的常见问题
"""
import json
import os
import re
import subprocess
from pathlib import Path
def run_ruff_check(directory: str) -> list[dict]:
"""运行 ruff 检查并返回问题列表"""
try:
result = subprocess.run(
["ruff", "check", "--select=E,W,F,I", "--output-format=json", directory],
capture_output=True,
text=True,
check=False,
)
if result.stdout:
return json.loads(result.stdout)
return []
except Exception as e:
print(f"Ruff check failed: {e}")
return []
def fix_bare_except(content: str) -> str:
"""修复裸异常捕获 - 将 bare except: 改为 except Exception:"""
pattern = r'except\s*:\s*\n'
replacement = 'except Exception:\n'
return re.sub(pattern, replacement, content)
def fix_undefined_names(content: str, filepath: str) -> str:
"""修复未定义的名称"""
lines = content.split('\n')
modified = False
import_map = {
'ExportEntity': 'from export_manager import ExportEntity',
'ExportRelation': 'from export_manager import ExportRelation',
'ExportTranscript': 'from export_manager import ExportTranscript',
'WorkflowManager': 'from workflow_manager import WorkflowManager',
'PluginManager': 'from plugin_manager import PluginManager',
'OpsManager': 'from ops_manager import OpsManager',
'urllib': 'import urllib.parse',
}
undefined_names = set()
for name, import_stmt in import_map.items():
if name in content and import_stmt not in content:
undefined_names.add((name, import_stmt))
if undefined_names:
import_idx = 0
for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '):
import_idx = i + 1
for name, import_stmt in sorted(undefined_names):
lines.insert(import_idx, import_stmt)
import_idx += 1
modified = True
if modified:
return '\n'.join(lines)
return content
def fix_file(filepath: str, issues: list[dict]) -> tuple[bool, list[str], list[str]]:
"""修复单个文件的问题"""
with open(filepath, 'r', encoding='utf-8') as f:
original_content = f.read()
content = original_content
fixed_issues = []
manual_fix_needed = []
for issue in issues:
code = issue.get('code', '')
message = issue.get('message', '')
line_num = issue['location']['row']
if code == 'F821':
content = fix_undefined_names(content, filepath)
if content != original_content:
fixed_issues.append(f"F821 - {message} (line {line_num})")
else:
manual_fix_needed.append(f"F821 - {message} (line {line_num})")
elif code == 'E501':
manual_fix_needed.append(f"E501 (line {line_num})")
content = fix_bare_except(content)
if content != original_content:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
return True, fixed_issues, manual_fix_needed
return False, fixed_issues, manual_fix_needed
def main():
base_dir = Path("/root/.openclaw/workspace/projects/insightflow")
backend_dir = base_dir / "backend"
print("=" * 60)
print("InsightFlow 代码自动修复")
print("=" * 60)
print("\n1. 扫描代码问题...")
issues = run_ruff_check(str(backend_dir))
issues_by_file = {}
for issue in issues:
filepath = issue.get('filename', '')
if filepath not in issues_by_file:
issues_by_file[filepath] = []
issues_by_file[filepath].append(issue)
print(f" 发现 {len(issues)} 个问题,分布在 {len(issues_by_file)} 个文件中")
issue_types = {}
for issue in issues:
code = issue.get('code', 'UNKNOWN')
issue_types[code] = issue_types.get(code, 0) + 1
print("\n2. 问题类型统计:")
for code, count in sorted(issue_types.items(), key=lambda x: -x[1]):
print(f" - {code}: {count}")
print("\n3. 尝试自动修复...")
fixed_files = []
all_fixed_issues = []
all_manual_fixes = []
for filepath, file_issues in issues_by_file.items():
if not os.path.exists(filepath):
continue
modified, fixed, manual = fix_file(filepath, file_issues)
if modified:
fixed_files.append(filepath)
all_fixed_issues.extend(fixed)
all_manual_fixes.extend([(filepath, m) for m in manual])
print(f" 直接修改了 {len(fixed_files)} 个文件")
print(f" 自动修复了 {len(all_fixed_issues)} 个问题")
print("\n4. 运行 ruff 自动格式化...")
try:
subprocess.run(
["ruff", "format", str(backend_dir)],
capture_output=True,
check=False,
)
print(" 格式化完成")
except Exception as e:
print(f" 格式化失败: {e}")
print("\n5. 再次检查...")
remaining_issues = run_ruff_check(str(backend_dir))
print(f" 剩余 {len(remaining_issues)} 个问题需要手动处理")
report = {
'total_issues': len(issues),
'fixed_files': len(fixed_files),
'fixed_issues': len(all_fixed_issues),
'remaining_issues': len(remaining_issues),
'issue_types': issue_types,
'manual_fix_needed': all_manual_fixes[:30],
}
return report
if __name__ == "__main__":
report = main()
print("\n" + "=" * 60)
print("修复报告")
print("=" * 60)
print(f"总问题数: {report['total_issues']}")
print(f"修复文件数: {report['fixed_files']}")
print(f"自动修复问题数: {report['fixed_issues']}")
print(f"剩余问题数: {report['remaining_issues']}")
print(f"\n需要手动处理的问题 (前30个):")
for filepath, issue in report['manual_fix_needed']:
print(f" - {filepath}: {issue}")

View File

@@ -334,14 +334,15 @@ class DatabaseManager:
"""INSERT INTO entity_mentions """INSERT INTO entity_mentions
(id, entity_id, transcript_id, start_pos, end_pos, text_snippet, confidence) (id, entity_id, transcript_id, start_pos, end_pos, text_snippet, confidence)
VALUES (?, ?, ?, ?, ?, ?, ?)""", VALUES (?, ?, ?, ?, ?, ?, ?)""",
(mention.id, (
mention.entity_id, mention.id,
mention.transcript_id, mention.entity_id,
mention.start_pos, mention.transcript_id,
mention.end_pos, mention.start_pos,
mention.text_snippet, mention.end_pos,
mention.confidence, mention.text_snippet,
), mention.confidence,
),
) )
conn.commit() conn.commit()
conn.close() conn.close()
@@ -372,12 +373,7 @@ class DatabaseManager:
"""INSERT INTO transcripts """INSERT INTO transcripts
(id, project_id, filename, full_text, type, created_at) (id, project_id, filename, full_text, type, created_at)
VALUES (?, ?, ?, ?, ?, ?)""", VALUES (?, ?, ?, ?, ?, ?)""",
(transcript_id, (transcript_id, project_id, filename, full_text, transcript_type, now),
project_id,
filename,
full_text,
transcript_type,
now),
) )
conn.commit() conn.commit()
conn.close() conn.close()

View File

@@ -156,6 +156,7 @@ class DocumentProcessor:
ext = os.path.splitext(filename.lower())[1] ext = os.path.splitext(filename.lower())[1]
return ext in self.supported_formats return ext in self.supported_formats
# 简单的文本提取器(不需要外部依赖) # 简单的文本提取器(不需要外部依赖)

View File

@@ -318,6 +318,7 @@ class EntityAligner:
return [] return []
# 简单的字符串相似度计算(不使用 embedding # 简单的字符串相似度计算(不使用 embedding

View File

@@ -34,6 +34,11 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from export_manager import ExportEntity
from export_manager import ExportRelation
from export_manager import ExportTranscript
from ops_manager import OpsManager
from plugin_manager import PluginManager
# Configure logger # Configure logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -563,6 +568,7 @@ async def rate_limit_middleware(request: Request, call_next):
return response return response
# 添加限流中间件 # 添加限流中间件
app.middleware("http")(rate_limit_middleware) app.middleware("http")(rate_limit_middleware)
@@ -645,6 +651,7 @@ class RateLimitStatus(BaseModel):
reset_time: int reset_time: int
window: str window: str
# 原有模型(保留) # 原有模型(保留)
@@ -713,6 +720,7 @@ class GlossaryTermCreate(BaseModel):
term: str term: str
pronunciation: str | None = "" pronunciation: str | None = ""
# ==================== Phase 7: Workflow Pydantic Models ==================== # ==================== Phase 7: Workflow Pydantic Models ====================
@@ -914,6 +922,7 @@ def get_doc_processor() -> "DocumentProcessor | None":
# Phase 7 Task 4: Collaboration Manager singleton # Phase 7 Task 4: Collaboration Manager singleton
_collaboration_manager: "CollaborationManager | None" = None _collaboration_manager: "CollaborationManager | None" = None
# Forward declaration for type hints # Forward declaration for type hints
class CollaborationManager: class CollaborationManager:
pass pass
@@ -926,6 +935,7 @@ def get_collab_manager() -> "CollaborationManager | None":
_collaboration_manager = get_collaboration_manager(db) _collaboration_manager = get_collaboration_manager(db)
return _collaboration_manager return _collaboration_manager
# Phase 2: Entity Edit API # Phase 2: Entity Edit API
@@ -997,6 +1007,7 @@ async def merge_entities_endpoint(
}, },
} }
# Phase 2: Relation Edit API # Phase 2: Relation Edit API
@@ -1063,6 +1074,7 @@ async def update_relation(relation_id: str, relation: RelationCreate, _=Depends(
"success": True, "success": True,
} }
# Phase 2: Transcript Edit API # Phase 2: Transcript Edit API
@@ -1103,6 +1115,7 @@ async def update_transcript(
"success": True, "success": True,
} }
# Phase 2: Manual Entity Creation # Phase 2: Manual Entity Creation
@@ -1290,6 +1303,7 @@ def align_entity(project_id: str, name: str, db, definition: str = "") -> Option
return None return None
# API Endpoints # API Endpoints
@@ -1427,6 +1441,7 @@ async def upload_audio(project_id: str, file: UploadFile = File(...), _=Depends(
created_at=datetime.now().isoformat(), created_at=datetime.now().isoformat(),
) )
# Phase 3: Document Upload API # Phase 3: Document Upload API
@@ -1549,6 +1564,7 @@ async def upload_document(project_id: str, file: UploadFile = File(...), _=Depen
"created_at": datetime.now().isoformat(), "created_at": datetime.now().isoformat(),
} }
# Phase 3: Knowledge Base API # Phase 3: Knowledge Base API
@@ -1644,6 +1660,7 @@ async def get_knowledge_base(project_id: str, _=Depends(verify_api_key)):
], ],
} }
# Phase 3: Glossary API # Phase 3: Glossary API
@@ -1686,6 +1703,7 @@ async def delete_glossary_term(term_id: str, _=Depends(verify_api_key)):
db.delete_glossary_term(term_id) db.delete_glossary_term(term_id)
return {"success": True} return {"success": True}
# Phase 3: Entity Alignment API # Phase 3: Entity Alignment API
@@ -1816,6 +1834,7 @@ async def get_entity_mentions(entity_id: str, _=Depends(verify_api_key)):
for m in mentions for m in mentions
] ]
# Health check - Legacy endpoint (deprecated, use /api/v1/health) # Health check - Legacy endpoint (deprecated, use /api/v1/health)
@@ -1838,6 +1857,7 @@ async def legacy_health_check():
"plugin_manager_available": PLUGIN_MANAGER_AVAILABLE, "plugin_manager_available": PLUGIN_MANAGER_AVAILABLE,
} }
# ==================== Phase 4: Agent 助手 API ==================== # ==================== Phase 4: Agent 助手 API ====================
@@ -2027,6 +2047,7 @@ async def agent_suggest(project_id: str, _=Depends(verify_api_key)):
return {"suggestions": []} return {"suggestions": []}
# ==================== Phase 4: 知识溯源 API ==================== # ==================== Phase 4: 知识溯源 API ====================
@@ -2106,6 +2127,7 @@ async def get_entity_evolution(entity_id: str, _=Depends(verify_api_key)):
], ],
} }
# ==================== Phase 4: 实体管理增强 API ==================== # ==================== Phase 4: 实体管理增强 API ====================
@@ -2121,6 +2143,7 @@ async def search_entities(project_id: str, q: str, _=Depends(verify_api_key)):
{"id": e.id, "name": e.name, "type": e.type, "definition": e.definition} for e in entities {"id": e.id, "name": e.name, "type": e.type, "definition": e.definition} for e in entities
] ]
# ==================== Phase 5: 时间线视图 API ==================== # ==================== Phase 5: 时间线视图 API ====================
@@ -2183,6 +2206,7 @@ async def get_entity_timeline(entity_id: str, _=Depends(verify_api_key)):
"total_count": len(timeline), "total_count": len(timeline),
} }
# ==================== Phase 5: 知识推理与问答增强 API ==================== # ==================== Phase 5: 知识推理与问答增强 API ====================
@@ -2336,6 +2360,7 @@ async def project_summary(project_id: str, req: SummaryRequest, _=Depends(verify
return {"project_id": project_id, "summary_type": req.summary_type, **summary**summary} return {"project_id": project_id, "summary_type": req.summary_type, **summary**summary}
# ==================== Phase 5: 实体属性扩展 API ==================== # ==================== Phase 5: 实体属性扩展 API ====================
@@ -2372,6 +2397,7 @@ class EntityAttributeBatchSet(BaseModel):
attributes: list[EntityAttributeSet] attributes: list[EntityAttributeSet]
change_reason: str | None = "" change_reason: str | None = ""
# 属性模板管理 API # 属性模板管理 API
@@ -2488,6 +2514,7 @@ async def delete_attribute_template_endpoint(template_id: str, _=Depends(verify_
return {"success": True, "message": f"Template {template_id} deleted"} return {"success": True, "message": f"Template {template_id} deleted"}
# 实体属性值管理 API # 实体属性值管理 API
@@ -2675,6 +2702,7 @@ async def delete_entity_attribute_endpoint(
return {"success": True, "message": "Attribute deleted"} return {"success": True, "message": "Attribute deleted"}
# 属性历史 API # 属性历史 API
@@ -2728,6 +2756,7 @@ async def get_template_history_endpoint(
for h in history for h in history
] ]
# 属性筛选搜索 API # 属性筛选搜索 API
@@ -2766,6 +2795,7 @@ async def search_entities_by_attributes_endpoint(
for e in entities for e in entities
] ]
# ==================== 导出功能 API ==================== # ==================== 导出功能 API ====================
@@ -3213,6 +3243,7 @@ async def export_transcript_markdown_endpoint(transcript_id: str, _=Depends(veri
}, },
) )
# ==================== Neo4j Graph Database API ==================== # ==================== Neo4j Graph Database API ====================
@@ -3470,6 +3501,7 @@ async def get_subgraph(request: GraphQueryRequest, _=Depends(verify_api_key)):
subgraph = manager.get_subgraph(request.entity_ids, request.depth) subgraph = manager.get_subgraph(request.entity_ids, request.depth)
return subgraph return subgraph
# ==================== Phase 6: API Key Management Endpoints ==================== # ==================== Phase 6: API Key Management Endpoints ====================
@@ -3729,6 +3761,7 @@ async def get_rate_limit_status(request: Request, _=Depends(verify_api_key)):
limit=limit, remaining=info.remaining, reset_time=info.reset_time, window="minute" limit=limit, remaining=info.remaining, reset_time=info.reset_time, window="minute"
) )
# ==================== Phase 6: System Endpoints ==================== # ==================== Phase 6: System Endpoints ====================
@@ -3767,6 +3800,7 @@ async def system_status():
return status return status
# ==================== Phase 7: Workflow Automation Endpoints ==================== # ==================== Phase 7: Workflow Automation Endpoints ====================
# Workflow Manager singleton # Workflow Manager singleton
@@ -4065,6 +4099,7 @@ async def get_workflow_stats_endpoint(workflow_id: str, days: int = 30, _=Depend
return WorkflowStatsResponse(**stats) return WorkflowStatsResponse(**stats)
# ==================== Phase 7: Webhook Endpoints ==================== # ==================== Phase 7: Webhook Endpoints ====================
@@ -4251,6 +4286,7 @@ async def test_webhook_endpoint(webhook_id: str, _=Depends(verify_api_key)):
else: else:
raise HTTPException(status_code=400, detail="Webhook test failed") raise HTTPException(status_code=400, detail="Webhook test failed")
# ==================== Phase 7: Multimodal Support Endpoints ==================== # ==================== Phase 7: Multimodal Support Endpoints ====================
# Pydantic Models for Multimodal API # Pydantic Models for Multimodal API
@@ -5124,6 +5160,7 @@ async def suggest_multimodal_merges_endpoint(project_id: str, _=Depends(verify_a
], ],
} }
# ==================== Phase 7: Multimodal Support API ==================== # ==================== Phase 7: Multimodal Support API ====================
@@ -5163,6 +5200,7 @@ class MultimodalProfileResponse(BaseModel):
entity_id: str entity_id: str
entity_name: str entity_name: str
# ==================== Phase 7 Task 7: Plugin Management Pydantic Models ==================== # ==================== Phase 7 Task 7: Plugin Management Pydantic Models ====================
@@ -5342,6 +5380,7 @@ def get_plugin_manager_instance() -> "PluginManager | None":
_plugin_manager_instance = get_plugin_manager(db) _plugin_manager_instance = get_plugin_manager(db)
return _plugin_manager_instance return _plugin_manager_instance
# ==================== Phase 7 Task 7: Plugin Management Endpoints ==================== # ==================== Phase 7 Task 7: Plugin Management Endpoints ====================
@@ -5490,6 +5529,7 @@ async def delete_plugin_endpoint(plugin_id: str, _=Depends(verify_api_key)):
return {"success": True, "message": "Plugin deleted successfully"} return {"success": True, "message": "Plugin deleted successfully"}
# ==================== Phase 7 Task 7: Chrome Extension Endpoints ==================== # ==================== Phase 7 Task 7: Chrome Extension Endpoints ====================
@@ -5621,6 +5661,7 @@ async def chrome_import_webpage_endpoint(request: ChromeExtensionImportRequest):
return result return result
# ==================== Phase 7 Task 7: Bot Endpoints ==================== # ==================== Phase 7 Task 7: Bot Endpoints ====================
@@ -5813,6 +5854,7 @@ async def send_bot_message_endpoint(
return {"success": success, "message": "Message sent" if success else "Failed to send message"} return {"success": success, "message": "Message sent" if success else "Failed to send message"}
# ==================== Phase 7 Task 7: Integration Endpoints ==================== # ==================== Phase 7 Task 7: Integration Endpoints ====================
@@ -5997,6 +6039,7 @@ async def trigger_integration_endpoint(
"message": "Triggered successfully" if success else "Trigger failed", "message": "Triggered successfully" if success else "Trigger failed",
} }
# ==================== Phase 7 Task 7: WebDAV Endpoints ==================== # ==================== Phase 7 Task 7: WebDAV Endpoints ====================
@@ -6168,6 +6211,7 @@ async def get_openapi():
tags=app.openapi_tags, tags=app.openapi_tags,
) )
# Serve frontend - MUST be last to not override API routes # Serve frontend - MUST be last to not override API routes
app.mount("/", StaticFiles(directory="frontend", html=True), name="frontend") app.mount("/", StaticFiles(directory="frontend", html=True), name="frontend")
@@ -6375,6 +6419,7 @@ async def regenerate_plugin_key(plugin_id: str, api_key: str = Depends(verify_ap
return {"success": True, "api_key": new_key} return {"success": True, "api_key": new_key}
# ==================== Chrome Extension API ==================== # ==================== Chrome Extension API ====================
@@ -6449,6 +6494,7 @@ URL: {request.url}
message="Content saved successfully", message="Content saved successfully",
) )
# ==================== Bot API ==================== # ==================== Bot API ====================
@@ -6517,6 +6563,7 @@ async def list_bot_sessions(
for s in sessions for s in sessions
] ]
# ==================== Webhook Integration API ==================== # ==================== Webhook Integration API ====================
@@ -6636,6 +6683,7 @@ async def receive_webhook(
return {"success": True, "endpoint_id": endpoint.id, "received_at": datetime.now().isoformat()} return {"success": True, "endpoint_id": endpoint.id, "received_at": datetime.now().isoformat()}
# ==================== WebDAV API ==================== # ==================== WebDAV API ====================
@@ -6759,6 +6807,7 @@ async def trigger_webdav_sync(sync_id: str, api_key: str = Depends(verify_api_ke
return {"success": True, "sync_id": sync_id, "status": "running", "message": "Sync started"} return {"success": True, "sync_id": sync_id, "status": "running", "message": "Sync started"}
# ==================== Plugin Activity Logs ==================== # ==================== Plugin Activity Logs ====================
@@ -6789,6 +6838,7 @@ async def get_plugin_logs(
] ]
} }
# ==================== Phase 7 Task 3: Security & Compliance API ==================== # ==================== Phase 7 Task 3: Security & Compliance API ====================
# Pydantic models for security API # Pydantic models for security API
@@ -6905,6 +6955,7 @@ class AccessRequestResponse(BaseModel):
expires_at: str | None = None expires_at: str | None = None
created_at: str created_at: str
# ==================== Audit Logs API ==================== # ==================== Audit Logs API ====================
@@ -6970,6 +7021,7 @@ async def get_audit_stats(
return AuditStatsResponse(**stats) return AuditStatsResponse(**stats)
# ==================== Encryption API ==================== # ==================== Encryption API ====================
@@ -7057,6 +7109,7 @@ async def get_encryption_config(project_id: str, api_key: str = Depends(verify_a
updated_at=config.updated_at, updated_at=config.updated_at,
) )
# ==================== Data Masking API ==================== # ==================== Data Masking API ====================
@@ -7232,6 +7285,7 @@ async def apply_masking(
original_text=request.text, masked_text=masked_text, applied_rules=applied_rules original_text=request.text, masked_text=masked_text, applied_rules=applied_rules
) )
# ==================== Data Access Policy API ==================== # ==================== Data Access Policy API ====================
@@ -7330,6 +7384,7 @@ async def check_access_permission(
return {"allowed": allowed, "reason": reason if not allowed else None} return {"allowed": allowed, "reason": reason if not allowed else None}
# ==================== Access Request API ==================== # ==================== Access Request API ====================
@@ -7429,6 +7484,7 @@ async def reject_access_request(
created_at=access_request.created_at, created_at=access_request.created_at,
) )
# ========================================== # ==========================================
# Phase 7 Task 4: 协作与共享 API # Phase 7 Task 4: 协作与共享 API
# ========================================== # ==========================================
@@ -7476,6 +7532,7 @@ class TeamMemberInvite(BaseModel):
class TeamMemberRoleUpdate(BaseModel): class TeamMemberRoleUpdate(BaseModel):
role: str role: str
# ----- 项目分享 ----- # ----- 项目分享 -----
@@ -7615,6 +7672,7 @@ async def revoke_share_link(share_id: str, revoked_by: str = "current_user"):
return {"success": True, "message": "Share link revoked"} return {"success": True, "message": "Share link revoked"}
# ----- 评论和批注 ----- # ----- 评论和批注 -----
@@ -7752,6 +7810,7 @@ async def delete_comment(comment_id: str, deleted_by: str = "current_user"):
return {"success": True, "message": "Comment deleted"} return {"success": True, "message": "Comment deleted"}
# ----- 变更历史 ----- # ----- 变更历史 -----
@@ -7845,6 +7904,7 @@ async def revert_change(record_id: str, reverted_by: str = "current_user"):
return {"success": True, "message": "Change reverted"} return {"success": True, "message": "Change reverted"}
# ----- 团队成员 ----- # ----- 团队成员 -----
@@ -7956,6 +8016,7 @@ async def check_project_permissions(project_id: str, user_id: str = "current_use
return {"has_access": True, "role": user_member.role, "permissions": user_member.permissions} return {"has_access": True, "role": user_member.role, "permissions": user_member.permissions}
# ==================== Phase 7 Task 6: Advanced Search & Discovery ==================== # ==================== Phase 7 Task 6: Advanced Search & Discovery ====================
@@ -8144,6 +8205,7 @@ async def index_project_for_search(project_id: str, _=Depends(verify_api_key)):
else: else:
raise HTTPException(status_code=500, detail="Failed to index project") raise HTTPException(status_code=500, detail="Failed to index project")
# ==================== Phase 7 Task 8: Performance & Scaling ==================== # ==================== Phase 7 Task 8: Performance & Scaling ====================
@@ -8329,6 +8391,7 @@ async def list_shards(_=Depends(verify_api_key)):
], ],
} }
# ============================================ # ============================================
# Phase 8: Multi-Tenant SaaS APIs # Phase 8: Multi-Tenant SaaS APIs
# ============================================ # ============================================
@@ -8370,6 +8433,7 @@ class InviteMemberRequest(BaseModel):
class UpdateMemberRequest(BaseModel): class UpdateMemberRequest(BaseModel):
role: str | None = None role: str | None = None
# Tenant Management APIs # Tenant Management APIs
@@ -8481,6 +8545,7 @@ async def delete_tenant(tenant_id: str, _=Depends(verify_api_key)):
return {"message": "Tenant deleted successfully"} return {"message": "Tenant deleted successfully"}
# Domain Management APIs # Domain Management APIs
@@ -8566,6 +8631,7 @@ async def remove_domain(tenant_id: str, domain_id: str, _=Depends(verify_api_key
return {"message": "Domain removed successfully"} return {"message": "Domain removed successfully"}
# Branding APIs # Branding APIs
@@ -8641,6 +8707,7 @@ async def get_branding_css(tenant_id: str):
return PlainTextResponse(content=css, media_type="text/css") return PlainTextResponse(content=css, media_type="text/css")
# Member Management APIs # Member Management APIs
@@ -8730,6 +8797,7 @@ async def remove_member(tenant_id: str, member_id: str, _=Depends(verify_api_key
return {"message": "Member removed successfully"} return {"message": "Member removed successfully"}
# Usage & Limits APIs # Usage & Limits APIs
@@ -8762,6 +8830,7 @@ async def check_resource_limit(tenant_id: str, resource_type: str, _=Depends(ver
"usage_percentage": round(current / limit * 100, 2) if limit > 0 else 0, "usage_percentage": round(current / limit * 100, 2) if limit > 0 else 0,
} }
# Public tenant resolution API (for custom domains) # Public tenant resolution API (for custom domains)
@@ -8837,6 +8906,7 @@ async def detailed_health_check():
return health return health
# ==================== Phase 8: Multi-Tenant SaaS API ==================== # ==================== Phase 8: Multi-Tenant SaaS API ====================
# Pydantic Models for Tenant API # Pydantic Models for Tenant API
@@ -8960,6 +9030,7 @@ class TenantStatsResponse(BaseModel):
api_calls_today: int api_calls_today: int
api_calls_month: int api_calls_month: int
# Tenant API Endpoints # Tenant API Endpoints
@@ -9077,6 +9148,7 @@ async def delete_tenant_endpoint(tenant_id: str, _=Depends(verify_api_key)):
return {"success": True, "message": f"Tenant {tenant_id} deleted"} return {"success": True, "message": f"Tenant {tenant_id} deleted"}
# Tenant Domain API # Tenant Domain API
@@ -9165,6 +9237,7 @@ async def remove_tenant_domain_endpoint(tenant_id: str, domain_id: str, _=Depend
return {"success": True, "message": "Domain removed successfully"} return {"success": True, "message": "Domain removed successfully"}
# Tenant Branding API # Tenant Branding API
@@ -9217,6 +9290,7 @@ async def get_tenant_theme_css_endpoint(tenant_id: str):
return PlainTextResponse(content=branding.get_theme_css(), media_type="text/css") return PlainTextResponse(content=branding.get_theme_css(), media_type="text/css")
# Tenant Member API # Tenant Member API
@@ -9340,6 +9414,7 @@ async def remove_tenant_member_endpoint(
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=403, detail=str(e)) raise HTTPException(status_code=403, detail=str(e))
# Tenant Role API # Tenant Role API
@@ -9425,6 +9500,7 @@ async def list_tenant_permissions_endpoint(_=Depends(verify_api_key)):
"permissions": [{"id": k, "name": v} for k, v in tenant_manager.PERMISSION_NAMES.items()] "permissions": [{"id": k, "name": v} for k, v in tenant_manager.PERMISSION_NAMES.items()]
} }
# Tenant Resolution API # Tenant Resolution API
@@ -9462,6 +9538,7 @@ async def get_tenant_context_endpoint(tenant_id: str, _=Depends(verify_api_key))
return context return context
# ============================================ # ============================================
# Phase 8 Task 2: Subscription & Billing APIs # Phase 8 Task 2: Subscription & Billing APIs
# ============================================ # ============================================
@@ -9518,6 +9595,7 @@ class CreateCheckoutSessionRequest(BaseModel):
success_url: str = Field(..., description="支付成功回调URL") success_url: str = Field(..., description="支付成功回调URL")
cancel_url: str = Field(..., description="支付取消回调URL") cancel_url: str = Field(..., description="支付取消回调URL")
# Subscription Plan APIs # Subscription Plan APIs
@@ -9578,6 +9656,7 @@ async def get_subscription_plan(plan_id: str, _=Depends(verify_api_key)):
"created_at": plan.created_at.isoformat(), "created_at": plan.created_at.isoformat(),
} }
# Subscription APIs # Subscription APIs
@@ -9716,6 +9795,7 @@ async def cancel_subscription(
except (RuntimeError, ValueError, TypeError) as e: except (RuntimeError, ValueError, TypeError) as e:
raise HTTPException(status_code=400, detail=str(e)) raise HTTPException(status_code=400, detail=str(e))
# Usage APIs # Usage APIs
@@ -9765,6 +9845,7 @@ async def get_usage_summary(
return summary return summary
# Payment APIs # Payment APIs
@@ -9831,6 +9912,7 @@ async def get_payment(tenant_id: str, payment_id: str, _=Depends(verify_api_key)
"created_at": payment.created_at.isoformat(), "created_at": payment.created_at.isoformat(),
} }
# Invoice APIs # Invoice APIs
@@ -9901,6 +9983,7 @@ async def get_invoice(tenant_id: str, invoice_id: str, _=Depends(verify_api_key)
"created_at": invoice.created_at.isoformat(), "created_at": invoice.created_at.isoformat(),
} }
# Refund APIs # Refund APIs
@@ -10015,6 +10098,7 @@ async def process_refund(
else: else:
raise HTTPException(status_code=400, detail="Invalid action") raise HTTPException(status_code=400, detail="Invalid action")
# Billing History API # Billing History API
@@ -10055,6 +10139,7 @@ async def get_billing_history(
"total": len(history), "total": len(history),
} }
# Payment Provider Integration APIs # Payment Provider Integration APIs
@@ -10127,6 +10212,7 @@ async def create_wechat_order(
except (RuntimeError, ValueError, TypeError) as e: except (RuntimeError, ValueError, TypeError) as e:
raise HTTPException(status_code=400, detail=str(e)) raise HTTPException(status_code=400, detail=str(e))
# Webhook Handlers # Webhook Handlers
@@ -10180,6 +10266,7 @@ async def wechat_webhook(request: Request):
else: else:
raise HTTPException(status_code=400, detail="Webhook processing failed") raise HTTPException(status_code=400, detail="Webhook processing failed")
# ==================== Phase 8: Enterprise Features API ==================== # ==================== Phase 8: Enterprise Features API ====================
# Pydantic Models for Enterprise # Pydantic Models for Enterprise
@@ -10284,6 +10371,7 @@ class RetentionPolicyUpdate(BaseModel):
archive_encryption: bool | None = None archive_encryption: bool | None = None
is_active: bool | None = None is_active: bool | None = None
# SSO/SAML APIs # SSO/SAML APIs
@@ -10465,6 +10553,7 @@ async def get_sso_metadata_endpoint(
"slo_url": f"{base_url}/api/v1/sso/saml/{tenant_id}/slo", "slo_url": f"{base_url}/api/v1/sso/saml/{tenant_id}/slo",
} }
# SCIM APIs # SCIM APIs
@@ -10600,6 +10689,7 @@ async def list_scim_users_endpoint(
"total": len(users), "total": len(users),
} }
# Audit Log Export APIs # Audit Log Export APIs
@@ -10740,6 +10830,7 @@ async def download_audit_export_endpoint(
"expires_at": export.expires_at.isoformat() if export.expires_at else None, "expires_at": export.expires_at.isoformat() if export.expires_at else None,
} }
# Data Retention Policy APIs # Data Retention Policy APIs
@@ -10950,6 +11041,7 @@ async def list_retention_jobs_endpoint(
"total": len(jobs), "total": len(jobs),
} }
# ============================================ # ============================================
# Phase 8 Task 7: Globalization & Localization API # Phase 8 Task 7: Globalization & Localization API
# ============================================ # ============================================
@@ -11015,6 +11107,7 @@ class ConvertTimezoneRequest(BaseModel):
from_tz: str = Field(..., description="源时区") from_tz: str = Field(..., description="源时区")
to_tz: str = Field(..., description="目标时区") to_tz: str = Field(..., description="目标时区")
# Translation APIs # Translation APIs
@@ -11145,6 +11238,7 @@ async def list_translations(
"total": len(translations), "total": len(translations),
} }
# Language APIs # Language APIs
@@ -11205,6 +11299,7 @@ async def get_language(code: str):
"calendar_type": lang.calendar_type, "calendar_type": lang.calendar_type,
} }
# Data Center APIs # Data Center APIs
@@ -11331,6 +11426,7 @@ async def set_tenant_data_center(
"created_at": mapping.created_at.isoformat(), "created_at": mapping.created_at.isoformat(),
} }
# Payment Method APIs # Payment Method APIs
@@ -11381,6 +11477,7 @@ async def get_localized_payment_methods(
return {"country_code": country_code, "language": language, "payment_methods": methods} return {"country_code": country_code, "language": language, "payment_methods": methods}
# Country APIs # Country APIs
@@ -11442,6 +11539,7 @@ async def get_country(code: str):
"vat_rate": country.vat_rate, "vat_rate": country.vat_rate,
} }
# Localization Settings APIs # Localization Settings APIs
@@ -11538,6 +11636,7 @@ async def update_localization_settings(
"updated_at": settings.updated_at.isoformat(), "updated_at": settings.updated_at.isoformat(),
} }
# Formatting APIs # Formatting APIs
@@ -11661,6 +11760,7 @@ async def get_calendar_info(
return info return info
# ============================================ # ============================================
# Phase 8 Task 4: AI 能力增强 API # Phase 8 Task 4: AI 能力增强 API
# ============================================ # ============================================
@@ -11734,6 +11834,7 @@ class PredictionFeedbackRequest(BaseModel):
actual_value: str actual_value: str
is_correct: bool is_correct: bool
# 自定义模型管理 API # 自定义模型管理 API
@@ -11909,6 +12010,7 @@ async def predict_with_custom_model(request: PredictRequest):
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) raise HTTPException(status_code=400, detail=str(e))
# 多模态分析 API # 多模态分析 API
@@ -11973,6 +12075,7 @@ async def list_multimodal_analyses(
] ]
} }
# 知识图谱 RAG API # 知识图谱 RAG API
@@ -12063,6 +12166,7 @@ async def query_kg_rag(
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) raise HTTPException(status_code=400, detail=str(e))
# 智能摘要 API # 智能摘要 API
@@ -12113,6 +12217,7 @@ async def list_smart_summaries(
# 这里需要从数据库查询,暂时返回空列表 # 这里需要从数据库查询,暂时返回空列表
return {"summaries": []} return {"summaries": []}
# 预测模型 API # 预测模型 API
@@ -12302,6 +12407,7 @@ async def update_prediction_feedback(request: PredictionFeedbackRequest):
return {"status": "success", "message": "Feedback updated"} return {"status": "success", "message": "Feedback updated"}
# ==================== Phase 8 Task 5: Growth & Analytics Endpoints ==================== # ==================== Phase 8 Task 5: Growth & Analytics Endpoints ====================
# Pydantic Models for Growth API # Pydantic Models for Growth API
@@ -12418,6 +12524,7 @@ def get_growth_manager_instance() -> "GrowthManager | None":
_growth_manager = GrowthManager() _growth_manager = GrowthManager()
return _growth_manager return _growth_manager
# ==================== 用户行为分析 API ==================== # ==================== 用户行为分析 API ====================
@@ -12514,6 +12621,7 @@ async def get_user_profile(tenant_id: str, user_id: str):
"engagement_score": profile.engagement_score, "engagement_score": profile.engagement_score,
} }
# ==================== 转化漏斗 API ==================== # ==================== 转化漏斗 API ====================
@@ -12592,6 +12700,7 @@ async def calculate_retention(
return retention return retention
# ==================== A/B 测试 API ==================== # ==================== A/B 测试 API ====================
@@ -12782,6 +12891,7 @@ async def stop_experiment_endpoint(experiment_id: str):
"end_date": experiment.end_date.isoformat() if experiment.end_date else None, "end_date": experiment.end_date.isoformat() if experiment.end_date else None,
} }
# ==================== 邮件营销 API ==================== # ==================== 邮件营销 API ====================
@@ -12959,6 +13069,7 @@ async def create_automation_workflow_endpoint(request: CreateAutomationWorkflowR
"created_at": workflow.created_at, "created_at": workflow.created_at,
} }
# ==================== 推荐系统 API ==================== # ==================== 推荐系统 API ====================
@@ -13101,6 +13212,7 @@ async def check_team_incentive_eligibility(tenant_id: str, current_tier: str, te
] ]
} }
# Serve frontend - MUST be last to not override API routes # Serve frontend - MUST be last to not override API routes
# ============================================ # ============================================
@@ -13269,6 +13381,7 @@ def get_developer_ecosystem_manager_instance() -> "DeveloperEcosystemManager | N
_developer_ecosystem_manager = DeveloperEcosystemManager() _developer_ecosystem_manager = DeveloperEcosystemManager()
return _developer_ecosystem_manager return _developer_ecosystem_manager
# ==================== SDK Release & Management API ==================== # ==================== SDK Release & Management API ====================
@@ -13481,6 +13594,7 @@ async def add_sdk_version_endpoint(sdk_id: str, request: SDKVersionCreate):
"created_at": version.created_at, "created_at": version.created_at,
} }
# ==================== Template Market API ==================== # ==================== Template Market API ====================
@@ -13733,6 +13847,7 @@ async def get_template_reviews_endpoint(
] ]
} }
# ==================== Plugin Market API ==================== # ==================== Plugin Market API ====================
@@ -13985,6 +14100,7 @@ async def get_plugin_reviews_endpoint(
] ]
} }
# ==================== Developer Revenue Sharing API ==================== # ==================== Developer Revenue Sharing API ====================
@@ -14033,6 +14149,7 @@ async def get_developer_revenue_summary_endpoint(developer_id: str):
return summary return summary
# ==================== Developer Profile & Management API ==================== # ==================== Developer Profile & Management API ====================
@@ -14167,6 +14284,7 @@ async def update_developer_stats_endpoint(developer_id: str):
return {"success": True, "message": "Developer stats updated"} return {"success": True, "message": "Developer stats updated"}
# ==================== Code Examples API ==================== # ==================== Code Examples API ====================
@@ -14284,6 +14402,7 @@ async def copy_code_example_endpoint(example_id: str):
return {"success": True, "message": "Code copied"} return {"success": True, "message": "Code copied"}
# ==================== API Documentation API ==================== # ==================== API Documentation API ====================
@@ -14331,6 +14450,7 @@ async def get_api_documentation_endpoint(doc_id: str):
"generated_by": doc.generated_by, "generated_by": doc.generated_by,
} }
# ==================== Developer Portal API ==================== # ==================== Developer Portal API ====================
@@ -14422,6 +14542,7 @@ async def get_portal_config_endpoint(config_id: str):
"is_active": config.is_active, "is_active": config.is_active,
} }
# ==================== Phase 8 Task 8: Operations & Monitoring Endpoints ==================== # ==================== Phase 8 Task 8: Operations & Monitoring Endpoints ====================
# Ops Manager singleton # Ops Manager singleton
@@ -14434,6 +14555,7 @@ def get_ops_manager_instance() -> "OpsManager | None":
_ops_manager = get_ops_manager() _ops_manager = get_ops_manager()
return _ops_manager return _ops_manager
# Pydantic Models for Ops API # Pydantic Models for Ops API
@@ -14562,6 +14684,7 @@ class BackupJobCreate(BaseModel):
compression_enabled: bool = Field(default=True, description="是否压缩") compression_enabled: bool = Field(default=True, description="是否压缩")
storage_location: str | None = Field(default=None, description="存储位置") storage_location: str | None = Field(default=None, description="存储位置")
# Alert Rules API # Alert Rules API
@@ -14737,6 +14860,7 @@ async def delete_alert_rule_endpoint(rule_id: str, _=Depends(verify_api_key)):
return {"success": True, "message": "Alert rule deleted"} return {"success": True, "message": "Alert rule deleted"}
# Alert Channels API # Alert Channels API
@@ -14819,6 +14943,7 @@ async def test_alert_channel_endpoint(channel_id: str, _=Depends(verify_api_key)
else: else:
raise HTTPException(status_code=400, detail="Failed to send test alert") raise HTTPException(status_code=400, detail="Failed to send test alert")
# Alerts API # Alerts API
@@ -14893,6 +15018,7 @@ async def resolve_alert_endpoint(alert_id: str, _=Depends(verify_api_key)):
return {"success": True, "message": "Alert resolved"} return {"success": True, "message": "Alert resolved"}
# Resource Metrics API # Resource Metrics API
@@ -14960,6 +15086,7 @@ async def get_resource_metrics_endpoint(
for m in metrics for m in metrics
] ]
# Capacity Planning API # Capacity Planning API
@@ -15026,6 +15153,7 @@ async def list_capacity_plans_endpoint(tenant_id: str, _=Depends(verify_api_key)
for plan in plans for plan in plans
] ]
# Auto Scaling API # Auto Scaling API
@@ -15120,6 +15248,7 @@ async def list_scaling_events_endpoint(
for event in events for event in events
] ]
# Health Check API # Health Check API
@@ -15205,6 +15334,7 @@ async def execute_health_check_endpoint(check_id: str, _=Depends(verify_api_key)
"checked_at": result.checked_at, "checked_at": result.checked_at,
} }
# Backup API # Backup API
@@ -15311,6 +15441,7 @@ async def list_backup_records_endpoint(
for record in records for record in records
] ]
# Cost Optimization API # Cost Optimization API
@@ -15447,5 +15578,6 @@ async def apply_cost_optimization_suggestion_endpoint(
}, },
} }
if __name__ == "__main__": if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000) uvicorn.run(app, host="0.0.0.0", port=8000)

View File

@@ -988,6 +988,7 @@ def close_neo4j_manager() -> None:
_neo4j_manager.close() _neo4j_manager.close()
_neo4j_manager = None _neo4j_manager = None
# 便捷函数 # 便捷函数

View File

@@ -139,6 +139,7 @@ class ShardInfo:
created_at: str = "" created_at: str = ""
last_accessed: str = "" last_accessed: str = ""
# ==================== Redis 缓存层 ==================== # ==================== Redis 缓存层 ====================
@@ -598,6 +599,7 @@ class CacheManager:
return count return count
# ==================== 数据库分片 ==================== # ==================== 数据库分片 ====================
@@ -900,6 +902,7 @@ class DatabaseSharding:
"message": "Rebalancing analysis completed", "message": "Rebalancing analysis completed",
} }
# ==================== 异步任务队列 ==================== # ==================== 异步任务队列 ====================
@@ -1284,6 +1287,7 @@ class TaskQueue:
"backend": "celery" if self.use_celery else "memory", "backend": "celery" if self.use_celery else "memory",
} }
# ==================== 性能监控 ==================== # ==================== 性能监控 ====================
@@ -1603,6 +1607,7 @@ class PerformanceMonitor:
return deleted return deleted
# ==================== 性能装饰器 ==================== # ==================== 性能装饰器 ====================
@@ -1678,6 +1683,7 @@ def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | Non
return decorator return decorator
# ==================== 性能管理器 ==================== # ==================== 性能管理器 ====================

View File

@@ -18,6 +18,8 @@ from enum import Enum
from typing import Any from typing import Any
import httpx import httpx
from plugin_manager import PluginManager
import urllib.parse
# Constants # Constants
UUID_LENGTH = 8 # UUID 截断长度 UUID_LENGTH = 8 # UUID 截断长度

View File

@@ -171,6 +171,7 @@ def get_rate_limiter() -> RateLimiter:
_rate_limiter = RateLimiter() _rate_limiter = RateLimiter()
return _rate_limiter return _rate_limiter
# 限流装饰器(用于函数级别限流) # 限流装饰器(用于函数级别限流)

View File

@@ -174,6 +174,7 @@ class TextEmbedding:
model_name: str model_name: str
created_at: str created_at: str
# ==================== 全文搜索 ==================== # ==================== 全文搜索 ====================
@@ -785,6 +786,7 @@ class FullTextSearch:
conn.close() conn.close()
return stats return stats
# ==================== 语义搜索 ==================== # ==================== 语义搜索 ====================
@@ -1148,6 +1150,7 @@ class SemanticSearch:
print(f"删除 embedding 失败: {e}") print(f"删除 embedding 失败: {e}")
return False return False
# ==================== 实体关系路径发现 ==================== # ==================== 实体关系路径发现 ====================
@@ -1620,6 +1623,7 @@ class EntityPathDiscovery:
bridge_scores.sort(key=lambda x: x["bridge_score"], reverse=True) bridge_scores.sort(key=lambda x: x["bridge_score"], reverse=True)
return bridge_scores[:20] # 返回前20 return bridge_scores[:20] # 返回前20
# ==================== 知识缺口识别 ==================== # ==================== 知识缺口识别 ====================
@@ -2025,6 +2029,7 @@ class KnowledgeGapDetection:
return recommendations return recommendations
# ==================== 搜索管理器 ==================== # ==================== 搜索管理器 ====================
@@ -2212,6 +2217,7 @@ def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
_search_manager = SearchManager(db_path) _search_manager = SearchManager(db_path)
return _search_manager return _search_manager
# 便捷函数 # 便捷函数

View File

@@ -297,9 +297,7 @@ class SecurityManager:
""") """)
# 创建索引 # 创建索引
cursor.execute( cursor.execute("CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)")
"CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)"
)
cursor.execute( cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_audit_logs_resource " "CREATE INDEX IF NOT EXISTS idx_audit_logs_resource "
"ON audit_logs(resource_type, resource_id)" "ON audit_logs(resource_type, resource_id)"

View File

@@ -1610,6 +1610,7 @@ class TenantManager:
status=row["status"], status=row["status"],
) )
# ==================== 租户上下文管理 ==================== # ==================== 租户上下文管理 ====================

View File

@@ -380,5 +380,6 @@ async def main():
traceback.print_exc() traceback.print_exc()
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())

View File

@@ -741,5 +741,6 @@ async def main():
tester = TestGrowthManager() tester = TestGrowthManager()
await tester.run_all_tests() await tester.run_all_tests()
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())

View File

@@ -27,6 +27,8 @@ from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_EXECUTED
from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.interval import IntervalTrigger
from workflow_manager import WorkflowManager
import urllib.parse
# Constants # Constants
UUID_LENGTH = 8 # UUID 截断长度 UUID_LENGTH = 8 # UUID 截断长度