Add frontend loading imporvements

This commit is contained in:
Urtzi Alfaro
2025-12-27 21:30:42 +01:00
parent 6e3a6590d6
commit 54662dde79
21 changed files with 799 additions and 363 deletions

View 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)}"
)