Delete legacy alerts
This commit is contained in:
@@ -10,7 +10,6 @@ from .data_client import DataClient
|
||||
from .messaging import (
|
||||
publish_forecast_generated,
|
||||
publish_batch_forecast_completed,
|
||||
publish_forecast_alert,
|
||||
ForecastingStatusPublisher
|
||||
)
|
||||
|
||||
@@ -22,6 +21,5 @@ __all__ = [
|
||||
"DataClient",
|
||||
"publish_forecast_generated",
|
||||
"publish_batch_forecast_completed",
|
||||
"publish_forecast_alert",
|
||||
"ForecastingStatusPublisher"
|
||||
]
|
||||
@@ -18,7 +18,6 @@ from app.services.data_client import DataClient
|
||||
from app.repositories import (
|
||||
ForecastRepository,
|
||||
PredictionBatchRepository,
|
||||
ForecastAlertRepository,
|
||||
PerformanceMetricRepository,
|
||||
PredictionCacheRepository
|
||||
)
|
||||
@@ -36,7 +35,7 @@ logger = structlog.get_logger()
|
||||
class EnhancedForecastingService:
|
||||
"""
|
||||
Enhanced forecasting service using repository pattern.
|
||||
Handles forecast generation, batch processing, and alerting with proper data abstraction.
|
||||
Handles forecast generation, batch processing with proper data abstraction.
|
||||
"""
|
||||
|
||||
def __init__(self, database_manager=None):
|
||||
@@ -55,7 +54,6 @@ class EnhancedForecastingService:
|
||||
return {
|
||||
'forecast': ForecastRepository(session),
|
||||
'batch': PredictionBatchRepository(session),
|
||||
'alert': ForecastAlertRepository(session),
|
||||
'performance': PerformanceMetricRepository(session),
|
||||
'cache': PredictionCacheRepository(session)
|
||||
}
|
||||
@@ -165,15 +163,6 @@ class EnhancedForecastingService:
|
||||
logger.error("Failed to delete forecast", error=str(e))
|
||||
return False
|
||||
|
||||
async def get_tenant_alerts(self, tenant_id: str, active_only: bool = True,
|
||||
skip: int = 0, limit: int = 50) -> List[Dict]:
|
||||
"""Get tenant alerts"""
|
||||
try:
|
||||
# Implementation would use repository pattern
|
||||
return []
|
||||
except Exception as e:
|
||||
logger.error("Failed to get tenant alerts", error=str(e))
|
||||
raise
|
||||
|
||||
async def get_tenant_forecast_statistics(self, tenant_id: str) -> Dict[str, Any]:
|
||||
"""Get tenant forecast statistics"""
|
||||
@@ -246,7 +235,7 @@ class EnhancedForecastingService:
|
||||
request: ForecastRequest
|
||||
) -> ForecastResponse:
|
||||
"""
|
||||
Generate forecast using repository pattern with caching and alerting.
|
||||
Generate forecast using repository pattern with caching.
|
||||
"""
|
||||
start_time = datetime.utcnow()
|
||||
|
||||
@@ -339,8 +328,6 @@ class EnhancedForecastingService:
|
||||
expires_in_hours=24
|
||||
)
|
||||
|
||||
# Step 8: Check for alerts
|
||||
await self._check_and_create_alerts(forecast, adjusted_prediction, repos)
|
||||
|
||||
logger.info("Enhanced forecast generated successfully",
|
||||
forecast_id=forecast.id,
|
||||
@@ -398,8 +385,6 @@ class EnhancedForecastingService:
|
||||
# Get forecast summary
|
||||
forecast_summary = await repos['forecast'].get_forecast_summary(tenant_id)
|
||||
|
||||
# Get alert statistics
|
||||
alert_stats = await repos['alert'].get_alert_statistics(tenant_id)
|
||||
|
||||
# Get batch statistics
|
||||
batch_stats = await repos['batch'].get_batch_statistics(tenant_id)
|
||||
@@ -415,7 +400,6 @@ class EnhancedForecastingService:
|
||||
return {
|
||||
"tenant_id": tenant_id,
|
||||
"forecast_analytics": forecast_summary,
|
||||
"alert_analytics": alert_stats,
|
||||
"batch_analytics": batch_stats,
|
||||
"cache_performance": cache_stats,
|
||||
"performance_trends": performance_trends,
|
||||
@@ -469,51 +453,6 @@ class EnhancedForecastingService:
|
||||
error=str(e))
|
||||
raise DatabaseError(f"Failed to create batch: {str(e)}")
|
||||
|
||||
async def _check_and_create_alerts(self, forecast, prediction: Dict[str, Any], repos: Dict):
|
||||
"""Check forecast results and create alerts if necessary"""
|
||||
try:
|
||||
alerts_to_create = []
|
||||
|
||||
# Check for high demand alert
|
||||
if prediction['prediction'] > 100: # Threshold for high demand
|
||||
alerts_to_create.append({
|
||||
"tenant_id": str(forecast.tenant_id),
|
||||
"forecast_id": str(forecast.id), # Convert UUID to string
|
||||
"alert_type": "high_demand",
|
||||
"severity": "high" if prediction['prediction'] > 200 else "medium",
|
||||
"message": f"High demand predicted for inventory product {str(forecast.inventory_product_id)}: {prediction['prediction']:.1f} units"
|
||||
})
|
||||
|
||||
# Check for low demand alert
|
||||
elif prediction['prediction'] < 10: # Threshold for low demand
|
||||
alerts_to_create.append({
|
||||
"tenant_id": str(forecast.tenant_id),
|
||||
"forecast_id": str(forecast.id), # Convert UUID to string
|
||||
"alert_type": "low_demand",
|
||||
"severity": "low",
|
||||
"message": f"Low demand predicted for inventory product {str(forecast.inventory_product_id)}: {prediction['prediction']:.1f} units"
|
||||
})
|
||||
|
||||
# Check for stockout risk (very low prediction with narrow confidence interval)
|
||||
confidence_interval = prediction['upper_bound'] - prediction['lower_bound']
|
||||
if prediction['prediction'] < 5 and confidence_interval < 10:
|
||||
alerts_to_create.append({
|
||||
"tenant_id": str(forecast.tenant_id),
|
||||
"forecast_id": str(forecast.id), # Convert UUID to string
|
||||
"alert_type": "stockout_risk",
|
||||
"severity": "critical",
|
||||
"message": f"Stockout risk for inventory product {str(forecast.inventory_product_id)}: predicted {prediction['prediction']:.1f} units with high confidence"
|
||||
})
|
||||
|
||||
# Create alerts
|
||||
for alert_data in alerts_to_create:
|
||||
await repos['alert'].create_alert(alert_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Failed to create alerts",
|
||||
forecast_id=forecast.id,
|
||||
error=str(e))
|
||||
# Don't raise - alerts are not critical for forecast generation
|
||||
|
||||
def _create_forecast_response_from_cache(self, cache_entry) -> ForecastResponse:
|
||||
"""Create forecast response from cached entry"""
|
||||
|
||||
@@ -72,12 +72,6 @@ async def publish_forecast_completed(data: Dict[str, Any]):
|
||||
event = ForecastGeneratedEvent(service_name="forecasting_service", data=data, event_type="forecast.completed")
|
||||
await rabbitmq_client.publish_forecast_event(event_type="completed", forecast_data=event.to_dict())
|
||||
|
||||
async def publish_alert_created(data: Dict[str, Any]):
|
||||
"""Publish alert created event"""
|
||||
# Assuming 'alert.created' is a type of forecast event, or define a new exchange/publisher method
|
||||
if rabbitmq_client:
|
||||
event = ForecastGeneratedEvent(service_name="forecasting_service", data=data, event_type="alert.created")
|
||||
await rabbitmq_client.publish_forecast_event(event_type="alert.created", forecast_data=event.to_dict())
|
||||
|
||||
async def publish_batch_completed(data: Dict[str, Any]):
|
||||
"""Publish batch forecast completed event"""
|
||||
@@ -181,19 +175,6 @@ async def publish_batch_forecast_completed(data: dict) -> bool:
|
||||
logger.error("Failed to publish batch forecast event", error=str(e))
|
||||
return False
|
||||
|
||||
async def publish_forecast_alert(data: dict) -> bool:
|
||||
"""Publish forecast alert event"""
|
||||
try:
|
||||
if rabbitmq_client:
|
||||
await rabbitmq_client.publish_event(
|
||||
exchange="forecasting_events",
|
||||
routing_key="forecast.alert",
|
||||
message=data
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error("Failed to publish forecast alert event", error=str(e))
|
||||
return False
|
||||
|
||||
|
||||
# Publisher class for compatibility
|
||||
|
||||
Reference in New Issue
Block a user