Files
bakery-ia/services/production/app/api/production_dashboard.py

91 lines
3.6 KiB
Python
Raw Normal View History

2025-10-06 15:27:01 +02:00
# services/production/app/api/production_dashboard.py
"""
Production Dashboard API - Dashboard endpoints for production overview
"""
2025-12-13 23:57:54 +01:00
from fastapi import APIRouter, Depends, HTTPException, Path, Query, Request
2025-10-06 15:27:01 +02:00
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
2025-12-05 20:07:01 +01:00
from app.utils.cache import get_cached, set_cached, make_cache_key
2025-10-06 15:27:01 +02:00
logger = structlog.get_logger()
route_builder = RouteBuilder('production')
router = APIRouter(tags=["production-dashboard"])
2025-12-13 23:57:54 +01:00
def get_production_service(request: Request) -> ProductionService:
2025-10-06 15:27:01 +02:00
"""Dependency injection for production service"""
from app.core.database import database_manager
2025-12-13 23:57:54 +01:00
notification_service = getattr(request.app.state, 'notification_service', None)
return ProductionService(database_manager, settings, notification_service)
2025-10-06 15:27:01 +02:00
@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)
):
2025-12-05 20:07:01 +01:00
"""Get production dashboard summary with caching (60s TTL)"""
2025-10-06 15:27:01 +02:00
try:
2025-12-05 20:07:01 +01:00
# 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
2025-10-06 15:27:01 +02:00
summary = await production_service.get_dashboard_summary(tenant_id)
2025-12-05 20:07:01 +01:00
# 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))
2025-10-06 15:27:01 +02:00
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")