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
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}")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -7
View File
@@ -334,7 +334,8 @@ class DatabaseManager:
"""INSERT INTO entity_mentions
(id, entity_id, transcript_id, start_pos, end_pos, text_snippet, confidence)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(mention.id,
(
mention.id,
mention.entity_id,
mention.transcript_id,
mention.start_pos,
@@ -372,12 +373,7 @@ class DatabaseManager:
"""INSERT INTO transcripts
(id, project_id, filename, full_text, type, created_at)
VALUES (?, ?, ?, ?, ?, ?)""",
(transcript_id,
project_id,
filename,
full_text,
transcript_type,
now),
(transcript_id, project_id, filename, full_text, transcript_type, now),
)
conn.commit()
conn.close()
+1
View File
@@ -156,6 +156,7 @@ class DocumentProcessor:
ext = os.path.splitext(filename.lower())[1]
return ext in self.supported_formats
# 简单的文本提取器(不需要外部依赖)
+1
View File
@@ -318,6 +318,7 @@ class EntityAligner:
return []
# 简单的字符串相似度计算(不使用 embedding)
+132
View File
@@ -34,6 +34,11 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
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
logger = logging.getLogger(__name__)
@@ -563,6 +568,7 @@ async def rate_limit_middleware(request: Request, call_next):
return response
# 添加限流中间件
app.middleware("http")(rate_limit_middleware)
@@ -645,6 +651,7 @@ class RateLimitStatus(BaseModel):
reset_time: int
window: str
# 原有模型(保留)
@@ -713,6 +720,7 @@ class GlossaryTermCreate(BaseModel):
term: str
pronunciation: str | None = ""
# ==================== Phase 7: Workflow Pydantic Models ====================
@@ -914,6 +922,7 @@ def get_doc_processor() -> "DocumentProcessor | None":
# Phase 7 Task 4: Collaboration Manager singleton
_collaboration_manager: "CollaborationManager | None" = None
# Forward declaration for type hints
class CollaborationManager:
pass
@@ -926,6 +935,7 @@ def get_collab_manager() -> "CollaborationManager | None":
_collaboration_manager = get_collaboration_manager(db)
return _collaboration_manager
# Phase 2: Entity Edit API
@@ -997,6 +1007,7 @@ async def merge_entities_endpoint(
},
}
# Phase 2: Relation Edit API
@@ -1063,6 +1074,7 @@ async def update_relation(relation_id: str, relation: RelationCreate, _=Depends(
"success": True,
}
# Phase 2: Transcript Edit API
@@ -1103,6 +1115,7 @@ async def update_transcript(
"success": True,
}
# Phase 2: Manual Entity Creation
@@ -1290,6 +1303,7 @@ def align_entity(project_id: str, name: str, db, definition: str = "") -> Option
return None
# API Endpoints
@@ -1427,6 +1441,7 @@ async def upload_audio(project_id: str, file: UploadFile = File(...), _=Depends(
created_at=datetime.now().isoformat(),
)
# 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(),
}
# 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
@@ -1686,6 +1703,7 @@ async def delete_glossary_term(term_id: str, _=Depends(verify_api_key)):
db.delete_glossary_term(term_id)
return {"success": True}
# 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
]
# Health check - Legacy endpoint (deprecated, use /api/v1/health)
@@ -1838,6 +1857,7 @@ async def legacy_health_check():
"plugin_manager_available": PLUGIN_MANAGER_AVAILABLE,
}
# ==================== Phase 4: Agent 助手 API ====================
@@ -2027,6 +2047,7 @@ async def agent_suggest(project_id: str, _=Depends(verify_api_key)):
return {"suggestions": []}
# ==================== Phase 4: 知识溯源 API ====================
@@ -2106,6 +2127,7 @@ async def get_entity_evolution(entity_id: str, _=Depends(verify_api_key)):
],
}
# ==================== 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
]
# ==================== Phase 5: 时间线视图 API ====================
@@ -2183,6 +2206,7 @@ async def get_entity_timeline(entity_id: str, _=Depends(verify_api_key)):
"total_count": len(timeline),
}
# ==================== 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}
# ==================== Phase 5: 实体属性扩展 API ====================
@@ -2372,6 +2397,7 @@ class EntityAttributeBatchSet(BaseModel):
attributes: list[EntityAttributeSet]
change_reason: str | None = ""
# 属性模板管理 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"}
# 实体属性值管理 API
@@ -2675,6 +2702,7 @@ async def delete_entity_attribute_endpoint(
return {"success": True, "message": "Attribute deleted"}
# 属性历史 API
@@ -2728,6 +2756,7 @@ async def get_template_history_endpoint(
for h in history
]
# 属性筛选搜索 API
@@ -2766,6 +2795,7 @@ async def search_entities_by_attributes_endpoint(
for e in entities
]
# ==================== 导出功能 API ====================
@@ -3213,6 +3243,7 @@ async def export_transcript_markdown_endpoint(transcript_id: str, _=Depends(veri
},
)
# ==================== 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)
return subgraph
# ==================== 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"
)
# ==================== Phase 6: System Endpoints ====================
@@ -3767,6 +3800,7 @@ async def system_status():
return status
# ==================== Phase 7: Workflow Automation Endpoints ====================
# Workflow Manager singleton
@@ -4065,6 +4099,7 @@ async def get_workflow_stats_endpoint(workflow_id: str, days: int = 30, _=Depend
return WorkflowStatsResponse(**stats)
# ==================== Phase 7: Webhook Endpoints ====================
@@ -4251,6 +4286,7 @@ async def test_webhook_endpoint(webhook_id: str, _=Depends(verify_api_key)):
else:
raise HTTPException(status_code=400, detail="Webhook test failed")
# ==================== Phase 7: Multimodal Support Endpoints ====================
# 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 ====================
@@ -5163,6 +5200,7 @@ class MultimodalProfileResponse(BaseModel):
entity_id: str
entity_name: str
# ==================== 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)
return _plugin_manager_instance
# ==================== 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"}
# ==================== Phase 7 Task 7: Chrome Extension Endpoints ====================
@@ -5621,6 +5661,7 @@ async def chrome_import_webpage_endpoint(request: ChromeExtensionImportRequest):
return result
# ==================== 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"}
# ==================== Phase 7 Task 7: Integration Endpoints ====================
@@ -5997,6 +6039,7 @@ async def trigger_integration_endpoint(
"message": "Triggered successfully" if success else "Trigger failed",
}
# ==================== Phase 7 Task 7: WebDAV Endpoints ====================
@@ -6168,6 +6211,7 @@ async def get_openapi():
tags=app.openapi_tags,
)
# Serve frontend - MUST be last to not override API routes
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}
# ==================== Chrome Extension API ====================
@@ -6449,6 +6494,7 @@ URL: {request.url}
message="Content saved successfully",
)
# ==================== Bot API ====================
@@ -6517,6 +6563,7 @@ async def list_bot_sessions(
for s in sessions
]
# ==================== Webhook Integration API ====================
@@ -6636,6 +6683,7 @@ async def receive_webhook(
return {"success": True, "endpoint_id": endpoint.id, "received_at": datetime.now().isoformat()}
# ==================== 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"}
# ==================== Plugin Activity Logs ====================
@@ -6789,6 +6838,7 @@ async def get_plugin_logs(
]
}
# ==================== Phase 7 Task 3: Security & Compliance API ====================
# Pydantic models for security API
@@ -6905,6 +6955,7 @@ class AccessRequestResponse(BaseModel):
expires_at: str | None = None
created_at: str
# ==================== Audit Logs API ====================
@@ -6970,6 +7021,7 @@ async def get_audit_stats(
return AuditStatsResponse(**stats)
# ==================== 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,
)
# ==================== Data Masking API ====================
@@ -7232,6 +7285,7 @@ async def apply_masking(
original_text=request.text, masked_text=masked_text, applied_rules=applied_rules
)
# ==================== Data Access Policy API ====================
@@ -7330,6 +7384,7 @@ async def check_access_permission(
return {"allowed": allowed, "reason": reason if not allowed else None}
# ==================== Access Request API ====================
@@ -7429,6 +7484,7 @@ async def reject_access_request(
created_at=access_request.created_at,
)
# ==========================================
# Phase 7 Task 4: 协作与共享 API
# ==========================================
@@ -7476,6 +7532,7 @@ class TeamMemberInvite(BaseModel):
class TeamMemberRoleUpdate(BaseModel):
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"}
# ----- 评论和批注 -----
@@ -7752,6 +7810,7 @@ async def delete_comment(comment_id: str, deleted_by: str = "current_user"):
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"}
# ----- 团队成员 -----
@@ -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}
# ==================== 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:
raise HTTPException(status_code=500, detail="Failed to index project")
# ==================== Phase 7 Task 8: Performance & Scaling ====================
@@ -8329,6 +8391,7 @@ async def list_shards(_=Depends(verify_api_key)):
],
}
# ============================================
# Phase 8: Multi-Tenant SaaS APIs
# ============================================
@@ -8370,6 +8433,7 @@ class InviteMemberRequest(BaseModel):
class UpdateMemberRequest(BaseModel):
role: str | None = None
# Tenant Management APIs
@@ -8481,6 +8545,7 @@ async def delete_tenant(tenant_id: str, _=Depends(verify_api_key)):
return {"message": "Tenant deleted successfully"}
# 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"}
# Branding APIs
@@ -8641,6 +8707,7 @@ async def get_branding_css(tenant_id: str):
return PlainTextResponse(content=css, media_type="text/css")
# 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"}
# 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,
}
# Public tenant resolution API (for custom domains)
@@ -8837,6 +8906,7 @@ async def detailed_health_check():
return health
# ==================== Phase 8: Multi-Tenant SaaS API ====================
# Pydantic Models for Tenant API
@@ -8960,6 +9030,7 @@ class TenantStatsResponse(BaseModel):
api_calls_today: int
api_calls_month: int
# 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"}
# 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"}
# 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")
# Tenant Member API
@@ -9340,6 +9414,7 @@ async def remove_tenant_member_endpoint(
except ValueError as e:
raise HTTPException(status_code=403, detail=str(e))
# 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()]
}
# Tenant Resolution API
@@ -9462,6 +9538,7 @@ async def get_tenant_context_endpoint(tenant_id: str, _=Depends(verify_api_key))
return context
# ============================================
# Phase 8 Task 2: Subscription & Billing APIs
# ============================================
@@ -9518,6 +9595,7 @@ class CreateCheckoutSessionRequest(BaseModel):
success_url: str = Field(..., description="支付成功回调URL")
cancel_url: str = Field(..., description="支付取消回调URL")
# 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(),
}
# Subscription APIs
@@ -9716,6 +9795,7 @@ async def cancel_subscription(
except (RuntimeError, ValueError, TypeError) as e:
raise HTTPException(status_code=400, detail=str(e))
# Usage APIs
@@ -9765,6 +9845,7 @@ async def get_usage_summary(
return summary
# 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(),
}
# 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(),
}
# Refund APIs
@@ -10015,6 +10098,7 @@ async def process_refund(
else:
raise HTTPException(status_code=400, detail="Invalid action")
# Billing History API
@@ -10055,6 +10139,7 @@ async def get_billing_history(
"total": len(history),
}
# Payment Provider Integration APIs
@@ -10127,6 +10212,7 @@ async def create_wechat_order(
except (RuntimeError, ValueError, TypeError) as e:
raise HTTPException(status_code=400, detail=str(e))
# Webhook Handlers
@@ -10180,6 +10266,7 @@ async def wechat_webhook(request: Request):
else:
raise HTTPException(status_code=400, detail="Webhook processing failed")
# ==================== Phase 8: Enterprise Features API ====================
# Pydantic Models for Enterprise
@@ -10284,6 +10371,7 @@ class RetentionPolicyUpdate(BaseModel):
archive_encryption: bool | None = None
is_active: bool | None = None
# 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",
}
# SCIM APIs
@@ -10600,6 +10689,7 @@ async def list_scim_users_endpoint(
"total": len(users),
}
# 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,
}
# Data Retention Policy APIs
@@ -10950,6 +11041,7 @@ async def list_retention_jobs_endpoint(
"total": len(jobs),
}
# ============================================
# Phase 8 Task 7: Globalization & Localization API
# ============================================
@@ -11015,6 +11107,7 @@ class ConvertTimezoneRequest(BaseModel):
from_tz: str = Field(..., description="源时区")
to_tz: str = Field(..., description="目标时区")
# Translation APIs
@@ -11145,6 +11238,7 @@ async def list_translations(
"total": len(translations),
}
# Language APIs
@@ -11205,6 +11299,7 @@ async def get_language(code: str):
"calendar_type": lang.calendar_type,
}
# Data Center APIs
@@ -11331,6 +11426,7 @@ async def set_tenant_data_center(
"created_at": mapping.created_at.isoformat(),
}
# Payment Method APIs
@@ -11381,6 +11477,7 @@ async def get_localized_payment_methods(
return {"country_code": country_code, "language": language, "payment_methods": methods}
# Country APIs
@@ -11442,6 +11539,7 @@ async def get_country(code: str):
"vat_rate": country.vat_rate,
}
# Localization Settings APIs
@@ -11538,6 +11636,7 @@ async def update_localization_settings(
"updated_at": settings.updated_at.isoformat(),
}
# Formatting APIs
@@ -11661,6 +11760,7 @@ async def get_calendar_info(
return info
# ============================================
# Phase 8 Task 4: AI 能力增强 API
# ============================================
@@ -11734,6 +11834,7 @@ class PredictionFeedbackRequest(BaseModel):
actual_value: str
is_correct: bool
# 自定义模型管理 API
@@ -11909,6 +12010,7 @@ async def predict_with_custom_model(request: PredictRequest):
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
# 多模态分析 API
@@ -11973,6 +12075,7 @@ async def list_multimodal_analyses(
]
}
# 知识图谱 RAG API
@@ -12063,6 +12166,7 @@ async def query_kg_rag(
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
# 智能摘要 API
@@ -12113,6 +12217,7 @@ async def list_smart_summaries(
# 这里需要从数据库查询,暂时返回空列表
return {"summaries": []}
# 预测模型 API
@@ -12302,6 +12407,7 @@ async def update_prediction_feedback(request: PredictionFeedbackRequest):
return {"status": "success", "message": "Feedback updated"}
# ==================== Phase 8 Task 5: Growth & Analytics Endpoints ====================
# Pydantic Models for Growth API
@@ -12418,6 +12524,7 @@ def get_growth_manager_instance() -> "GrowthManager | None":
_growth_manager = GrowthManager()
return _growth_manager
# ==================== 用户行为分析 API ====================
@@ -12514,6 +12621,7 @@ async def get_user_profile(tenant_id: str, user_id: str):
"engagement_score": profile.engagement_score,
}
# ==================== 转化漏斗 API ====================
@@ -12592,6 +12700,7 @@ async def calculate_retention(
return retention
# ==================== 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,
}
# ==================== 邮件营销 API ====================
@@ -12959,6 +13069,7 @@ async def create_automation_workflow_endpoint(request: CreateAutomationWorkflowR
"created_at": workflow.created_at,
}
# ==================== 推荐系统 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
# ============================================
@@ -13269,6 +13381,7 @@ def get_developer_ecosystem_manager_instance() -> "DeveloperEcosystemManager | N
_developer_ecosystem_manager = DeveloperEcosystemManager()
return _developer_ecosystem_manager
# ==================== SDK Release & Management API ====================
@@ -13481,6 +13594,7 @@ async def add_sdk_version_endpoint(sdk_id: str, request: SDKVersionCreate):
"created_at": version.created_at,
}
# ==================== Template Market API ====================
@@ -13733,6 +13847,7 @@ async def get_template_reviews_endpoint(
]
}
# ==================== Plugin Market API ====================
@@ -13985,6 +14100,7 @@ async def get_plugin_reviews_endpoint(
]
}
# ==================== Developer Revenue Sharing API ====================
@@ -14033,6 +14149,7 @@ async def get_developer_revenue_summary_endpoint(developer_id: str):
return summary
# ==================== Developer Profile & Management API ====================
@@ -14167,6 +14284,7 @@ async def update_developer_stats_endpoint(developer_id: str):
return {"success": True, "message": "Developer stats updated"}
# ==================== Code Examples API ====================
@@ -14284,6 +14402,7 @@ async def copy_code_example_endpoint(example_id: str):
return {"success": True, "message": "Code copied"}
# ==================== API Documentation API ====================
@@ -14331,6 +14450,7 @@ async def get_api_documentation_endpoint(doc_id: str):
"generated_by": doc.generated_by,
}
# ==================== Developer Portal API ====================
@@ -14422,6 +14542,7 @@ async def get_portal_config_endpoint(config_id: str):
"is_active": config.is_active,
}
# ==================== Phase 8 Task 8: Operations & Monitoring Endpoints ====================
# Ops Manager singleton
@@ -14434,6 +14555,7 @@ def get_ops_manager_instance() -> "OpsManager | None":
_ops_manager = get_ops_manager()
return _ops_manager
# Pydantic Models for Ops API
@@ -14562,6 +14684,7 @@ class BackupJobCreate(BaseModel):
compression_enabled: bool = Field(default=True, description="是否压缩")
storage_location: str | None = Field(default=None, description="存储位置")
# 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"}
# Alert Channels API
@@ -14819,6 +14943,7 @@ async def test_alert_channel_endpoint(channel_id: str, _=Depends(verify_api_key)
else:
raise HTTPException(status_code=400, detail="Failed to send test alert")
# Alerts API
@@ -14893,6 +15018,7 @@ async def resolve_alert_endpoint(alert_id: str, _=Depends(verify_api_key)):
return {"success": True, "message": "Alert resolved"}
# Resource Metrics API
@@ -14960,6 +15086,7 @@ async def get_resource_metrics_endpoint(
for m in metrics
]
# Capacity Planning API
@@ -15026,6 +15153,7 @@ async def list_capacity_plans_endpoint(tenant_id: str, _=Depends(verify_api_key)
for plan in plans
]
# Auto Scaling API
@@ -15120,6 +15248,7 @@ async def list_scaling_events_endpoint(
for event in events
]
# 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,
}
# Backup API
@@ -15311,6 +15441,7 @@ async def list_backup_records_endpoint(
for record in records
]
# Cost Optimization API
@@ -15447,5 +15578,6 @@ async def apply_cost_optimization_suggestion_endpoint(
},
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
+1
View File
@@ -988,6 +988,7 @@ def close_neo4j_manager() -> None:
_neo4j_manager.close()
_neo4j_manager = None
# 便捷函数
+6
View File
@@ -139,6 +139,7 @@ class ShardInfo:
created_at: str = ""
last_accessed: str = ""
# ==================== Redis 缓存层 ====================
@@ -598,6 +599,7 @@ class CacheManager:
return count
# ==================== 数据库分片 ====================
@@ -900,6 +902,7 @@ class DatabaseSharding:
"message": "Rebalancing analysis completed",
}
# ==================== 异步任务队列 ====================
@@ -1284,6 +1287,7 @@ class TaskQueue:
"backend": "celery" if self.use_celery else "memory",
}
# ==================== 性能监控 ====================
@@ -1603,6 +1607,7 @@ class PerformanceMonitor:
return deleted
# ==================== 性能装饰器 ====================
@@ -1678,6 +1683,7 @@ def monitored(monitor: PerformanceMonitor, metric_type: str, endpoint: str | Non
return decorator
# ==================== 性能管理器 ====================
+2
View File
@@ -18,6 +18,8 @@ from enum import Enum
from typing import Any
import httpx
from plugin_manager import PluginManager
import urllib.parse
# Constants
UUID_LENGTH = 8 # UUID 截断长度
+1
View File
@@ -171,6 +171,7 @@ def get_rate_limiter() -> RateLimiter:
_rate_limiter = RateLimiter()
return _rate_limiter
# 限流装饰器(用于函数级别限流)
+6
View File
@@ -174,6 +174,7 @@ class TextEmbedding:
model_name: str
created_at: str
# ==================== 全文搜索 ====================
@@ -785,6 +786,7 @@ class FullTextSearch:
conn.close()
return stats
# ==================== 语义搜索 ====================
@@ -1148,6 +1150,7 @@ class SemanticSearch:
print(f"删除 embedding 失败: {e}")
return False
# ==================== 实体关系路径发现 ====================
@@ -1620,6 +1623,7 @@ class EntityPathDiscovery:
bridge_scores.sort(key=lambda x: x["bridge_score"], reverse=True)
return bridge_scores[:20] # 返回前20
# ==================== 知识缺口识别 ====================
@@ -2025,6 +2029,7 @@ class KnowledgeGapDetection:
return recommendations
# ==================== 搜索管理器 ====================
@@ -2212,6 +2217,7 @@ def get_search_manager(db_path: str = "insightflow.db") -> SearchManager:
_search_manager = SearchManager(db_path)
return _search_manager
# 便捷函数
+1 -3
View File
@@ -297,9 +297,7 @@ class SecurityManager:
""")
# 创建索引
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)"
)
cursor.execute("CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)")
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_audit_logs_resource "
"ON audit_logs(resource_type, resource_id)"
+1
View File
@@ -1610,6 +1610,7 @@ class TenantManager:
status=row["status"],
)
# ==================== 租户上下文管理 ====================
+1
View File
@@ -380,5 +380,6 @@ async def main():
traceback.print_exc()
if __name__ == "__main__":
asyncio.run(main())
+1
View File
@@ -741,5 +741,6 @@ async def main():
tester = TestGrowthManager()
await tester.run_all_tests()
if __name__ == "__main__":
asyncio.run(main())
+2
View File
@@ -27,6 +27,8 @@ from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_EXECUTED
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger
from workflow_manager import WorkflowManager
import urllib.parse
# Constants
UUID_LENGTH = 8 # UUID 截断长度