Files
bakery-ia/services/orchestrator/app/api/enterprise_dashboard.py
2025-11-30 09:12:40 +01:00

201 lines
7.9 KiB
Python

"""
Enterprise Dashboard API Endpoints for Orchestrator Service
"""
from fastapi import APIRouter, Depends, HTTPException
from typing import List, Optional, Dict, Any
from datetime import date
import structlog
from app.services.enterprise_dashboard_service import EnterpriseDashboardService
from shared.auth.tenant_access import verify_tenant_access_dep
from shared.clients.tenant_client import TenantServiceClient
from shared.clients.forecast_client import ForecastServiceClient
from shared.clients.production_client import ProductionServiceClient
from shared.clients.sales_client import SalesServiceClient
from shared.clients.inventory_client import InventoryServiceClient
from shared.clients.distribution_client import DistributionServiceClient
logger = structlog.get_logger()
router = APIRouter(prefix="/api/v1/tenants/{tenant_id}/enterprise", tags=["enterprise"])
# Add dependency injection function
from app.services.enterprise_dashboard_service import EnterpriseDashboardService
from shared.clients import (
get_tenant_client,
get_forecast_client,
get_production_client,
get_sales_client,
get_inventory_client,
get_procurement_client
)
# TODO: Add distribution client when available
# from shared.clients import get_distribution_client
def get_enterprise_dashboard_service() -> EnterpriseDashboardService:
from app.core.config import settings
tenant_client = get_tenant_client(settings)
forecast_client = get_forecast_client(settings)
production_client = get_production_client(settings)
sales_client = get_sales_client(settings)
inventory_client = get_inventory_client(settings)
distribution_client = None # TODO: Add when distribution service is ready
procurement_client = get_procurement_client(settings)
return EnterpriseDashboardService(
tenant_client=tenant_client,
forecast_client=forecast_client,
production_client=production_client,
sales_client=sales_client,
inventory_client=inventory_client,
distribution_client=distribution_client,
procurement_client=procurement_client
)
@router.get("/network-summary")
async def get_network_summary(
tenant_id: str,
enterprise_service: EnterpriseDashboardService = Depends(get_enterprise_dashboard_service),
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get network summary metrics for enterprise dashboard
"""
try:
# Verify user has network access
tenant_info = await enterprise_service.tenant_client.get_tenant(tenant_id)
if not tenant_info:
raise HTTPException(status_code=404, detail="Tenant not found")
if tenant_info.get('tenant_type') != 'parent':
raise HTTPException(status_code=403, detail="Only parent tenants can access enterprise dashboard")
result = await enterprise_service.get_network_summary(parent_tenant_id=tenant_id)
return result
except Exception as e:
logger.error(f"Error getting network summary: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to get network summary")
@router.get("/children-performance")
async def get_children_performance(
tenant_id: str,
metric: str = "sales",
period_days: int = 30,
enterprise_service: EnterpriseDashboardService = Depends(get_enterprise_dashboard_service),
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get anonymized performance ranking of child tenants
"""
try:
# Verify user has network access
tenant_info = await enterprise_service.tenant_client.get_tenant(tenant_id)
if not tenant_info:
raise HTTPException(status_code=404, detail="Tenant not found")
if tenant_info.get('tenant_type') != 'parent':
raise HTTPException(status_code=403, detail="Only parent tenants can access enterprise dashboard")
result = await enterprise_service.get_children_performance(
parent_tenant_id=tenant_id,
metric=metric,
period_days=period_days
)
return result
except Exception as e:
logger.error(f"Error getting children performance: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to get children performance")
@router.get("/distribution-overview")
async def get_distribution_overview(
tenant_id: str,
target_date: Optional[date] = None,
enterprise_service: EnterpriseDashboardService = Depends(get_enterprise_dashboard_service),
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get distribution overview for enterprise dashboard
"""
try:
# Verify user has network access
tenant_info = await enterprise_service.tenant_client.get_tenant(tenant_id)
if not tenant_info:
raise HTTPException(status_code=404, detail="Tenant not found")
if tenant_info.get('tenant_type') != 'parent':
raise HTTPException(status_code=403, detail="Only parent tenants can access enterprise dashboard")
if target_date is None:
target_date = date.today()
result = await enterprise_service.get_distribution_overview(
parent_tenant_id=tenant_id,
target_date=target_date
)
return result
except Exception as e:
logger.error(f"Error getting distribution overview: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to get distribution overview")
@router.get("/forecast-summary")
async def get_enterprise_forecast_summary(
tenant_id: str,
days_ahead: int = 7,
enterprise_service: EnterpriseDashboardService = Depends(get_enterprise_dashboard_service),
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get aggregated forecast summary for the enterprise network
"""
try:
# Verify user has network access
tenant_info = await enterprise_service.tenant_client.get_tenant(tenant_id)
if not tenant_info:
raise HTTPException(status_code=404, detail="Tenant not found")
if tenant_info.get('tenant_type') != 'parent':
raise HTTPException(status_code=403, detail="Only parent tenants can access enterprise dashboard")
result = await enterprise_service.get_enterprise_forecast_summary(
parent_tenant_id=tenant_id,
days_ahead=days_ahead
)
return result
except Exception as e:
logger.error(f"Error getting enterprise forecast summary: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to get enterprise forecast summary")
@router.get("/network-performance")
async def get_network_performance_metrics(
tenant_id: str,
start_date: Optional[date] = None,
end_date: Optional[date] = None,
enterprise_service: EnterpriseDashboardService = Depends(get_enterprise_dashboard_service),
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get aggregated performance metrics across the tenant network
"""
try:
# Verify user has network access
tenant_info = await enterprise_service.tenant_client.get_tenant(tenant_id)
if not tenant_info:
raise HTTPException(status_code=404, detail="Tenant not found")
if tenant_info.get('tenant_type') != 'parent':
raise HTTPException(status_code=403, detail="Only parent tenants can access enterprise dashboard")
if not start_date:
start_date = date.today()
if not end_date:
end_date = date.today()
result = await enterprise_service.get_network_performance_metrics(
parent_tenant_id=tenant_id,
start_date=start_date,
end_date=end_date
)
return result
except Exception as e:
logger.error(f"Error getting network performance metrics: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to get network performance metrics")