Files
bakery-ia/services/production/app/api/production_dashboard.py
2025-12-13 23:57:54 +01:00

91 lines
3.6 KiB
Python

# services/production/app/api/production_dashboard.py
"""
Production Dashboard API - Dashboard endpoints for production overview
"""
from fastapi import APIRouter, Depends, HTTPException, Path, Query, Request
from typing import Optional
from datetime import date, datetime
from uuid import UUID
import structlog
from shared.auth.decorators import get_current_user_dep
from shared.routing import RouteBuilder
from app.services.production_service import ProductionService
from app.schemas.production import ProductionDashboardSummary
from app.core.config import settings
from app.utils.cache import get_cached, set_cached, make_cache_key
logger = structlog.get_logger()
route_builder = RouteBuilder('production')
router = APIRouter(tags=["production-dashboard"])
def get_production_service(request: Request) -> ProductionService:
"""Dependency injection for production service"""
from app.core.database import database_manager
notification_service = getattr(request.app.state, 'notification_service', None)
return ProductionService(database_manager, settings, notification_service)
@router.get(
route_builder.build_dashboard_route("summary"),
response_model=ProductionDashboardSummary
)
async def get_dashboard_summary(
tenant_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
production_service: ProductionService = Depends(get_production_service)
):
"""Get production dashboard summary with caching (60s TTL)"""
try:
# PHASE 2: Check cache first
cache_key = make_cache_key("production_dashboard", str(tenant_id))
cached_result = await get_cached(cache_key)
if cached_result is not None:
logger.debug("Cache hit for production dashboard", cache_key=cache_key, tenant_id=str(tenant_id))
return ProductionDashboardSummary(**cached_result)
# Cache miss - fetch from database
summary = await production_service.get_dashboard_summary(tenant_id)
# PHASE 2: Cache the result (60s TTL for production batches)
await set_cached(cache_key, summary.model_dump(), ttl=60)
logger.debug("Cached production dashboard", cache_key=cache_key, ttl=60, tenant_id=str(tenant_id))
logger.info("Retrieved production dashboard summary",
tenant_id=str(tenant_id))
return summary
except Exception as e:
logger.error("Error getting dashboard summary",
error=str(e), tenant_id=str(tenant_id))
raise HTTPException(status_code=500, detail="Failed to get dashboard summary")
@router.get(
route_builder.build_dashboard_route("requirements"),
response_model=dict
)
async def get_production_requirements(
tenant_id: UUID = Path(...),
date: Optional[date] = Query(None, description="Target date for production requirements"),
current_user: dict = Depends(get_current_user_dep),
production_service: ProductionService = Depends(get_production_service)
):
"""Get production requirements for procurement planning"""
try:
target_date = date or datetime.now().date()
requirements = await production_service.get_production_requirements(tenant_id, target_date)
logger.info("Retrieved production requirements for procurement",
tenant_id=str(tenant_id), date=target_date.isoformat())
return requirements
except Exception as e:
logger.error("Error getting production requirements",
error=str(e), tenant_id=str(tenant_id))
raise HTTPException(status_code=500, detail="Failed to get production requirements")