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,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()

View File

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

View File

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

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)

View File

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

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
# ==================== 性能管理器 ====================

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 截断长度

View File

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

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
# 便捷函数

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)"

View File

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

View File

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

View File

@@ -741,5 +741,6 @@ async def main():
tester = TestGrowthManager()
await tester.run_all_tests()
if __name__ == "__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.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger
from workflow_manager import WorkflowManager
import urllib.parse
# Constants
UUID_LENGTH = 8 # UUID 截断长度