# services/inventory/app/api/internal_alert_trigger.py """ Internal API for triggering inventory alerts. Used by demo session cloning to generate realistic inventory alerts. URL Pattern: /api/v1/tenants/{tenant_id}/inventory/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 inventory service correctly @router.post("/api/v1/tenants/{tenant_id}/inventory/internal/alerts/trigger") async def trigger_inventory_alerts( tenant_id: UUID = Path(..., description="Tenant ID to check inventory for"), request: Request = None ) -> dict: """ Trigger comprehensive inventory alert checks for a specific tenant (internal use only). This endpoint is called by the demo session cloning process after inventory data is seeded to generate realistic inventory alerts including: - Critical stock shortages - Expiring ingredients - Overstock situations 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 inventory scheduler from app state inventory_scheduler = getattr(request.app.state, 'inventory_scheduler', None) if not inventory_scheduler: logger.error("Inventory scheduler not initialized") raise HTTPException( status_code=500, detail="Inventory scheduler not available" ) # Trigger comprehensive inventory alert checks for the specific tenant logger.info("Triggering comprehensive inventory alert checks", tenant_id=str(tenant_id)) # Call the scheduler's manual trigger method result = await inventory_scheduler.trigger_manual_check(tenant_id) if result.get("success", False): logger.info( "Inventory alert checks completed successfully", tenant_id=str(tenant_id), alerts_generated=result.get("alerts_generated", 0) ) else: logger.error( "Inventory 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 inventory alerts", tenant_id=str(tenant_id), error=str(e), exc_info=True ) raise HTTPException( status_code=500, detail=f"Failed to trigger inventory alerts: {str(e)}" )