Merge branch 'review/pr-362'

This commit is contained in:
ajaysi
2026-03-02 11:38:58 +05:30
2 changed files with 44 additions and 18 deletions

View File

@@ -474,11 +474,11 @@ async def seo_dashboard_health_check():
# Phase 2B: Semantic health monitoring endpoint # Phase 2B: Semantic health monitoring endpoint
async def get_semantic_health(current_user: dict = Depends(get_current_user)) -> SemanticHealthMetric: async def get_semantic_health(current_user: dict = Depends(get_current_user)) -> SemanticHealthMetric:
""" """
Get real-time semantic health metrics for the user's content and competitors. Get the canonical semantic health summary for the user's content and competitors.
This endpoint provides Phase 2B semantic intelligence monitoring data. This endpoint provides Phase 2B semantic intelligence monitoring data.
Returns: Returns:
SemanticHealthMetric with current health status, score, and recommendations SemanticHealthMetric with health status, aggregate score, and recommendations.
""" """
try: try:
user_id = str(current_user.get('id')) user_id = str(current_user.get('id'))
@@ -487,7 +487,7 @@ async def get_semantic_health(current_user: dict = Depends(get_current_user)) ->
semantic_monitor = RealTimeSemanticMonitor(user_id) semantic_monitor = RealTimeSemanticMonitor(user_id)
# Get current semantic health (will use cache if available) # Get current semantic health (will use cache if available)
semantic_health = await semantic_monitor.check_semantic_health(user_id) semantic_health: SemanticHealthMetric = await semantic_monitor.check_semantic_health(user_id)
logger.info(f"[Semantic Health API] Retrieved health data for user {user_id}: {semantic_health.status} (score: {semantic_health.value:.2f})") logger.info(f"[Semantic Health API] Retrieved health data for user {user_id}: {semantic_health.status} (score: {semantic_health.value:.2f})")

View File

@@ -100,7 +100,7 @@ class RealTimeSemanticMonitor:
logger.info(f"Real-time semantic monitor initialized for user {user_id}") logger.info(f"Real-time semantic monitor initialized for user {user_id}")
async def check_semantic_health(self, user_id: Optional[str] = None) -> Any: async def check_semantic_health(self, user_id: Optional[str] = None) -> SemanticHealthMetric:
""" """
Public wrapper for semantic health check. Public wrapper for semantic health check.
Aggregates metrics into a single health status object. Aggregates metrics into a single health status object.
@@ -109,12 +109,19 @@ class RealTimeSemanticMonitor:
metrics = await self._check_semantic_health() metrics = await self._check_semantic_health()
if not metrics: if not metrics:
# Return default/unknown state if no metrics # Return a canonical semantic health summary when no metrics are available.
@dataclass return SemanticHealthMetric(
class HealthResult: metric_name="semantic_health",
status: str = "unknown" value=0.0,
value: float = 0.0 threshold=0.0,
return HealthResult() status="warning",
timestamp=datetime.utcnow().isoformat(),
description="No semantic health metrics available yet",
recommendations=[
"Run semantic analysis to populate health metrics",
"Check data sources and try again shortly"
]
)
# Aggregate metrics # Aggregate metrics
# 1. Status: "critical" if any critical, else "warning" if any warning, else "healthy" # 1. Status: "critical" if any critical, else "warning" if any warning, else "healthy"
@@ -129,12 +136,31 @@ class RealTimeSemanticMonitor:
# 2. Value: Average of metric values # 2. Value: Average of metric values
avg_value = sum(m.value for m in metrics) / len(metrics) avg_value = sum(m.value for m in metrics) / len(metrics)
@dataclass # 3. Threshold: Average threshold across health metrics
class HealthResult: avg_threshold = sum(m.threshold for m in metrics) / len(metrics)
status: str
value: float
return HealthResult(status=status, value=avg_value) # 4. Recommendations: de-duplicated recommendations from non-healthy metrics
recommendations = []
seen_recommendations = set()
for metric in metrics:
if metric.status != "healthy":
for recommendation in metric.recommendations:
if recommendation not in seen_recommendations:
seen_recommendations.add(recommendation)
recommendations.append(recommendation)
if not recommendations:
recommendations = ["Continue monitoring semantic performance"]
return SemanticHealthMetric(
metric_name="semantic_health",
value=avg_value,
threshold=avg_threshold,
status=status,
timestamp=datetime.utcnow().isoformat(),
description="Aggregated semantic health across monitoring metrics",
recommendations=recommendations,
)
async def start_monitoring(self, competitors: List[str] = None) -> bool: async def start_monitoring(self, competitors: List[str] = None) -> bool:
"""Start real-time semantic monitoring.""" """Start real-time semantic monitoring."""