Files
erp-ass/backend/app/core/executor.py
dazhuang acd73431ae feat: implement ERP AI Assistant Phase 1
Backend (FastAPI + SQLAlchemy + Claude API + RAG):
- Config management with Pydantic v2
- Database engine with connection pooling and SQL injection prevention
- AI engine with Claude API integration (support custom base URL)
- RAG engine with ChromaDB and sentence-transformers
- Requirement analysis service
- Config generation service
- Executor engine with SQL validation
- REST API endpoints: /analyze, /generate, /execute

Frontend (Vue 3 + Element Plus + Pinia):
- Complete 3-step workflow: analyze → generate → execute
- Step indicator with progress visualization
- Analysis result display with field table
- SQL preview with monospace font
- Execute confirmation dialog with safety warning
- Execution result display
- State management with Pinia
- API service integration

Security:
- SQL injection prevention with parameterized queries
- Dangerous SQL operation blocking
- Database password URL encoding
- Transaction auto-rollback
- Pydantic config validation

Features:
- Natural language requirement analysis
- Automated SQL configuration generation
- Safe execution with human review
- LAN access support
- Custom Claude API endpoint support

Documentation:
- README with quick start guide
- Quick start guide
- LAN access configuration
- Dependency fixes guide
- Claude API configuration
- Git operation guide
- Implementation report

Dependencies fixed:
- numpy<2.0.0 for chromadb compatibility
- sentence-transformers==2.7.0 for huggingface_hub compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 14:23:20 +00:00

147 lines
5.0 KiB
Python

"""Config Executor for ERP AI Assistant.
This module provides the ConfigExecutor class for validating and executing
SQL configuration statements with safety checks.
"""
import re
from typing import List, Tuple, Dict, Any
from loguru import logger
from app.core.db_engine import DatabaseEngine
class ConfigExecutor:
"""Executor for SQL configuration statements with safety validation.
This class validates SQL statements against dangerous operations before
execution and provides transaction-based execution with rollback support.
"""
# Dangerous SQL keywords that should be blocked
DANGEROUS_KEYWORDS = [
r"DROP\s+DATABASE",
r"DROP\s+TABLE",
r"TRUNCATE\s+TABLE",
r"DELETE\s+FROM",
r"UPDATE\s+.*\s+SET",
r"ALTER\s+TABLE\s+.*\s+DROP"
]
def __init__(self) -> None:
"""Initialize executor with database engine."""
self.db_engine = DatabaseEngine()
logger.info("ConfigExecutor initialized")
def validate_sql(self, sql: str) -> Tuple[bool, str]:
"""Validate SQL statement for safety.
Checks SQL against a list of dangerous keywords/patterns to prevent
destructive operations.
Args:
sql: SQL statement to validate
Returns:
Tuple of (is_valid, message) where is_valid indicates if SQL is safe
"""
if not sql or not sql.strip():
return False, "SQL语句为空"
sql_upper = sql.upper().strip()
# Check for dangerous operations
for pattern in self.DANGEROUS_KEYWORDS:
if re.search(pattern, sql_upper):
# Extract matched keyword for error message
match = re.search(pattern, sql_upper)
matched_keyword = match.group(0) if match else pattern
logger.warning(f"SQL validation failed: dangerous operation '{matched_keyword}' detected")
return False, f"危险操作被拦截: {matched_keyword}"
logger.debug(f"SQL validation passed: {sql[:50]}...")
return True, "SQL验证通过"
def execute_config(
self,
sql_list: List[str],
session_id: str
) -> Dict[str, Any]:
"""Execute a list of SQL statements in a transaction.
Validates all SQL statements before execution. If any validation fails,
no statements are executed.
Args:
sql_list: List of SQL statements to execute
session_id: Session ID for logging and tracking
Returns:
Dictionary containing:
- success: Boolean indicating overall success
- executed: List of executed SQL statements
- failed: Error message if execution failed, None otherwise
- message: Human-readable result message
"""
logger.info(f"[{session_id}] Starting config execution with {len(sql_list)} SQL statements")
results: Dict[str, Any] = {
"success": True,
"executed": [],
"failed": None,
"message": ""
}
try:
# Step 1: Validate all SQL statements
logger.debug(f"[{session_id}] Validating {len(sql_list)} SQL statements")
for i, sql in enumerate(sql_list):
is_valid, msg = self.validate_sql(sql)
if not is_valid:
error_msg = f"SQL #{i+1} 验证失败: {msg}"
logger.error(f"[{session_id}] {error_msg}")
raise ValueError(error_msg)
# Step 2: Execute transaction
logger.debug(f"[{session_id}] Executing transaction")
self.db_engine.execute_transaction(sql_list)
# Step 3: Record success
results["executed"] = sql_list
results["message"] = f"成功执行 {len(sql_list)} 条SQL"
logger.success(f"[{session_id}] {results['message']}")
except ValueError as e:
# Validation failure
results["success"] = False
results["failed"] = str(e)
results["message"] = f"执行失败: {e}"
logger.error(f"[{session_id}] {results['message']}")
except Exception as e:
# Execution failure
results["success"] = False
results["failed"] = str(e)
results["message"] = f"执行失败: {e}"
logger.error(f"[{session_id}] {results['message']}")
return results
def rollback(self, session_id: str) -> Dict[str, Any]:
"""Rollback executed operations for a session.
This is a placeholder for rollback functionality. Actual implementation
would require recording inverse SQL operations during execution.
Args:
session_id: Session ID to rollback
Returns:
Dictionary with success status and message
"""
logger.warning(f"[{session_id}] Rollback requested but not yet implemented")
return {
"success": False,
"message": "回滚功能待实现"
}