Improve onboarding

This commit is contained in:
Urtzi Alfaro
2025-12-18 13:26:32 +01:00
parent f76b3f8e6b
commit f10a2b92ea
42 changed files with 2175 additions and 984 deletions

View File

@@ -8,6 +8,8 @@ from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, Path, status
from sqlalchemy.ext.asyncio import AsyncSession
import httpx
import structlog
from app.core.database import get_db
from app.services.inventory_service import InventoryService
@@ -25,6 +27,8 @@ from shared.auth.access_control import require_user_role, admin_role_required, o
from shared.routing import RouteBuilder
from shared.security import create_audit_logger, AuditSeverity, AuditAction
logger = structlog.get_logger()
# Create route builder for consistent URL structure
route_builder = RouteBuilder('inventory')
@@ -61,6 +65,58 @@ async def create_ingredient(
):
"""Create a new ingredient (Admin/Manager only)"""
try:
# CRITICAL: Check subscription limit before creating
from app.core.config import settings
async with httpx.AsyncClient(timeout=5.0) as client:
try:
limit_check_response = await client.get(
f"{settings.TENANT_SERVICE_URL}/api/v1/tenants/subscriptions/{tenant_id}/can-add-product",
headers={
"x-user-id": str(current_user.get('user_id')),
"x-tenant-id": str(tenant_id)
}
)
if limit_check_response.status_code == 200:
limit_check = limit_check_response.json()
if not limit_check.get('can_add', False):
logger.warning(
"Product limit exceeded",
tenant_id=str(tenant_id),
current=limit_check.get('current_count'),
max=limit_check.get('max_allowed'),
reason=limit_check.get('reason')
)
raise HTTPException(
status_code=status.HTTP_402_PAYMENT_REQUIRED,
detail={
"error": "product_limit_exceeded",
"message": limit_check.get('reason', 'Product limit exceeded'),
"current_count": limit_check.get('current_count'),
"max_allowed": limit_check.get('max_allowed'),
"upgrade_required": True
}
)
else:
logger.warning(
"Failed to check product limit, allowing creation",
tenant_id=str(tenant_id),
status_code=limit_check_response.status_code
)
except httpx.TimeoutException:
logger.warning(
"Timeout checking product limit, allowing creation",
tenant_id=str(tenant_id)
)
except httpx.RequestError as e:
logger.warning(
"Error checking product limit, allowing creation",
tenant_id=str(tenant_id),
error=str(e)
)
# Extract user ID - handle service tokens
raw_user_id = current_user.get('user_id')
if current_user.get('type') == 'service':
@@ -73,13 +129,28 @@ async def create_ingredient(
service = InventoryService()
ingredient = await service.create_ingredient(ingredient_data, tenant_id, user_id)
logger.info(
"Ingredient created successfully",
tenant_id=str(tenant_id),
ingredient_id=str(ingredient.id),
ingredient_name=ingredient.name
)
return ingredient
except HTTPException:
raise
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e)
)
except Exception as e:
logger.error(
"Failed to create ingredient",
tenant_id=str(tenant_id),
error=str(e)
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to create ingredient"