73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, BackgroundTasks
|
||
|
|
from typing import List, Optional, Dict, Any
|
||
|
|
from datetime import datetime, date
|
||
|
|
import structlog
|
||
|
|
|
||
|
|
from app.schemas.forecast import (
|
||
|
|
ForecastRequest,
|
||
|
|
ForecastResponse,
|
||
|
|
BatchForecastRequest,
|
||
|
|
ForecastPerformanceResponse
|
||
|
|
)
|
||
|
|
from app.services.forecast_service import ForecastService
|
||
|
|
from app.services.messaging import publish_forecast_generated
|
||
|
|
|
||
|
|
# Import unified authentication
|
||
|
|
from shared.auth.decorators import (
|
||
|
|
get_current_user_dep,
|
||
|
|
get_current_tenant_id_dep
|
||
|
|
)
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/forecasts", tags=["forecasting"])
|
||
|
|
logger = structlog.get_logger()
|
||
|
|
|
||
|
|
@router.post("/generate", response_model=ForecastResponse)
|
||
|
|
async def generate_forecast(
|
||
|
|
request: ForecastRequest,
|
||
|
|
background_tasks: BackgroundTasks,
|
||
|
|
tenant_id: str = Depends(get_current_tenant_id_dep),
|
||
|
|
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||
|
|
):
|
||
|
|
"""Generate forecast for products"""
|
||
|
|
try:
|
||
|
|
logger.info("Generating forecast",
|
||
|
|
tenant_id=tenant_id,
|
||
|
|
user_id=current_user["user_id"],
|
||
|
|
products=len(request.products) if request.products else "all")
|
||
|
|
|
||
|
|
forecast_service = ForecastService()
|
||
|
|
|
||
|
|
# Ensure products belong to tenant
|
||
|
|
if request.products:
|
||
|
|
valid_products = await forecast_service.validate_products(
|
||
|
|
tenant_id, request.products
|
||
|
|
)
|
||
|
|
if len(valid_products) != len(request.products):
|
||
|
|
raise HTTPException(
|
||
|
|
status_code=400,
|
||
|
|
detail="Some products not found or not accessible"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Generate forecast
|
||
|
|
forecast = await forecast_service.generate_forecast(
|
||
|
|
tenant_id=tenant_id,
|
||
|
|
request=request,
|
||
|
|
user_id=current_user["user_id"]
|
||
|
|
)
|
||
|
|
|
||
|
|
# Publish event
|
||
|
|
background_tasks.add_task(
|
||
|
|
publish_forecast_generated,
|
||
|
|
forecast_id=forecast.id,
|
||
|
|
tenant_id=tenant_id,
|
||
|
|
user_id=current_user["user_id"]
|
||
|
|
)
|
||
|
|
|
||
|
|
return forecast
|
||
|
|
|
||
|
|
except HTTPException:
|
||
|
|
raise
|
||
|
|
except Exception as e:
|
||
|
|
logger.error("Failed to generate forecast", error=str(e))
|
||
|
|
raise HTTPException(status_code=500, detail=str(e))
|