""" Onboarding Status API Provides lightweight onboarding status checks by aggregating counts from multiple services """ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession import structlog import asyncio import httpx import os from app.core.database import get_db from app.core.config import settings from shared.auth.decorators import get_current_tenant_id_dep from shared.routing.route_builder import RouteBuilder logger = structlog.get_logger() router = APIRouter() route_builder = RouteBuilder("tenants") @router.get(route_builder.build_base_route("{tenant_id}/onboarding/status", include_tenant_prefix=False)) async def get_onboarding_status( tenant_id: str, db: AsyncSession = Depends(get_db) ): """ Get lightweight onboarding status by fetching counts from each service. Returns: - ingredients_count: Number of active ingredients - suppliers_count: Number of active suppliers - recipes_count: Number of active recipes - has_minimum_setup: Boolean indicating if minimum requirements are met - progress_percentage: Overall onboarding progress (0-100) """ try: # Service URLs from environment inventory_url = os.getenv("INVENTORY_SERVICE_URL", "http://inventory-service:8000") suppliers_url = os.getenv("SUPPLIERS_SERVICE_URL", "http://suppliers-service:8000") recipes_url = os.getenv("RECIPES_SERVICE_URL", "http://recipes-service:8000") # Fetch counts from all services in parallel async with httpx.AsyncClient(timeout=10.0) as client: results = await asyncio.gather( client.get( f"{inventory_url}/internal/count", params={"tenant_id": tenant_id} ), client.get( f"{suppliers_url}/internal/count", params={"tenant_id": tenant_id} ), client.get( f"{recipes_url}/internal/count", params={"tenant_id": tenant_id} ), return_exceptions=True ) # Extract counts with fallback to 0 ingredients_count = 0 suppliers_count = 0 recipes_count = 0 if not isinstance(results[0], Exception) and results[0].status_code == 200: ingredients_count = results[0].json().get("count", 0) if not isinstance(results[1], Exception) and results[1].status_code == 200: suppliers_count = results[1].json().get("count", 0) if not isinstance(results[2], Exception) and results[2].status_code == 200: recipes_count = results[2].json().get("count", 0) # Calculate minimum setup requirements # Minimum: 3 ingredients, 1 supplier, 1 recipe has_minimum_ingredients = ingredients_count >= 3 has_minimum_suppliers = suppliers_count >= 1 has_minimum_recipes = recipes_count >= 1 has_minimum_setup = all([ has_minimum_ingredients, has_minimum_suppliers, has_minimum_recipes ]) # Calculate progress percentage # Each requirement contributes 33.33% progress = 0 if has_minimum_ingredients: progress += 33 if has_minimum_suppliers: progress += 33 if has_minimum_recipes: progress += 34 return { "ingredients_count": ingredients_count, "suppliers_count": suppliers_count, "recipes_count": recipes_count, "has_minimum_setup": has_minimum_setup, "progress_percentage": progress, "requirements": { "ingredients": { "current": ingredients_count, "minimum": 3, "met": has_minimum_ingredients }, "suppliers": { "current": suppliers_count, "minimum": 1, "met": has_minimum_suppliers }, "recipes": { "current": recipes_count, "minimum": 1, "met": has_minimum_recipes } } } except Exception as e: logger.error("Failed to get onboarding status", tenant_id=tenant_id, error=str(e)) raise HTTPException( status_code=500, detail=f"Failed to get onboarding status: {str(e)}" )