# 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. URL Pattern: /api/v1/tenants/{tenant_id}/production/internal/alerts/trigger This follows the tenant-scoped pattern so gateway can proxy correctly. """ from fastapi import APIRouter, HTTPException, Request, Path from uuid import UUID import structlog logger = structlog.get_logger() router = APIRouter() # New URL pattern: tenant-scoped so gateway proxies to production service correctly @router.post("/api/v1/tenants/{tenant_id}/production/internal/alerts/trigger") async def trigger_production_alerts( tenant_id: UUID = Path(..., description="Tenant ID to check production for"), request: Request = None ) -> dict: """ Trigger comprehensive 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 alerts including: - Production delays - Equipment maintenance alerts - Batch start delays 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 scheduler from app state production_scheduler = getattr(request.app.state, 'production_scheduler', None) if not production_scheduler: logger.error("Production scheduler not initialized") raise HTTPException( status_code=500, detail="Production scheduler not available" ) # Trigger comprehensive production alert checks for the specific tenant logger.info("Triggering comprehensive production alert checks", tenant_id=str(tenant_id)) # Call the scheduler's manual trigger method result = await production_scheduler.trigger_manual_check(tenant_id) if result.get("success", False): logger.info( "Production alert checks completed successfully", tenant_id=str(tenant_id), alerts_generated=result.get("alerts_generated", 0) ) else: logger.error( "Production alert checks failed", tenant_id=str(tenant_id), error=result.get("error", "Unknown error") ) return result 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)}" )