86 lines
3.0 KiB
Python
86 lines
3.0 KiB
Python
|
|
# services/production/app/api/internal_alert_trigger.py
|
||
|
|
"""
|
||
|
|
Internal API for triggering production alerts.
|
||
|
|
Used by demo session cloning to generate realistic production delay alerts.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from fastapi import APIRouter, HTTPException, Request, Path
|
||
|
|
from uuid import UUID
|
||
|
|
import structlog
|
||
|
|
|
||
|
|
logger = structlog.get_logger()
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/api/internal/production-alerts/trigger/{tenant_id}")
|
||
|
|
async def trigger_production_alerts(
|
||
|
|
tenant_id: UUID = Path(..., description="Tenant ID to check production for"),
|
||
|
|
request: Request = None
|
||
|
|
) -> dict:
|
||
|
|
"""
|
||
|
|
Trigger production alert checks for a specific tenant (internal use only).
|
||
|
|
|
||
|
|
This endpoint is called by the demo session cloning process after production
|
||
|
|
batches are seeded to generate realistic production delay alerts.
|
||
|
|
|
||
|
|
Security: Protected by X-Internal-Service header check.
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
# Verify internal service header
|
||
|
|
if not request or request.headers.get("X-Internal-Service") not in ["demo-session", "internal"]:
|
||
|
|
logger.warning("Unauthorized internal API call", tenant_id=str(tenant_id))
|
||
|
|
raise HTTPException(
|
||
|
|
status_code=403,
|
||
|
|
detail="This endpoint is for internal service use only"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Get production alert service from app state
|
||
|
|
production_alert_service = getattr(request.app.state, 'production_alert_service', None)
|
||
|
|
|
||
|
|
if not production_alert_service:
|
||
|
|
logger.error("Production alert service not initialized")
|
||
|
|
raise HTTPException(
|
||
|
|
status_code=500,
|
||
|
|
detail="Production alert service not available"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Trigger production alert checks (checks all tenants, including this one)
|
||
|
|
logger.info("Triggering production alert checks", tenant_id=str(tenant_id))
|
||
|
|
await production_alert_service.check_production_delays()
|
||
|
|
|
||
|
|
# Return success (service checks all tenants, we can't get specific count)
|
||
|
|
result = {"total_alerts": 0, "message": "Production alert checks triggered"}
|
||
|
|
|
||
|
|
logger.info(
|
||
|
|
"Production alert checks completed",
|
||
|
|
tenant_id=str(tenant_id),
|
||
|
|
alerts_generated=result.get("total_alerts", 0)
|
||
|
|
)
|
||
|
|
|
||
|
|
return {
|
||
|
|
"success": True,
|
||
|
|
"tenant_id": str(tenant_id),
|
||
|
|
"alerts_generated": result.get("total_alerts", 0),
|
||
|
|
"breakdown": {
|
||
|
|
"critical": result.get("critical", 0),
|
||
|
|
"high": result.get("high", 0),
|
||
|
|
"medium": result.get("medium", 0),
|
||
|
|
"low": result.get("low", 0)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
except HTTPException:
|
||
|
|
raise
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(
|
||
|
|
"Error triggering production alerts",
|
||
|
|
tenant_id=str(tenant_id),
|
||
|
|
error=str(e),
|
||
|
|
exc_info=True
|
||
|
|
)
|
||
|
|
raise HTTPException(
|
||
|
|
status_code=500,
|
||
|
|
detail=f"Failed to trigger production alerts: {str(e)}"
|
||
|
|
)
|