Add frontend loading imporvements
This commit is contained in:
133
services/tenant/app/api/onboarding.py
Normal file
133
services/tenant/app/api/onboarding.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
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")
|
||||
|
||||
internal_api_key = settings.INTERNAL_API_KEY
|
||||
|
||||
# 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},
|
||||
headers={"X-Internal-API-Key": internal_api_key}
|
||||
),
|
||||
client.get(
|
||||
f"{suppliers_url}/internal/count",
|
||||
params={"tenant_id": tenant_id},
|
||||
headers={"X-Internal-API-Key": internal_api_key}
|
||||
),
|
||||
client.get(
|
||||
f"{recipes_url}/internal/count",
|
||||
params={"tenant_id": tenant_id},
|
||||
headers={"X-Internal-API-Key": internal_api_key}
|
||||
),
|
||||
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)}"
|
||||
)
|
||||
Reference in New Issue
Block a user