Files
bakery-ia/services/recipes/app/api/recipe_quality_configs.py
2025-10-06 15:27:01 +02:00

167 lines
5.5 KiB
Python

# services/recipes/app/api/recipe_quality_configs.py
"""
Recipe Quality Configuration API - Atomic CRUD operations on RecipeQualityConfiguration
"""
from fastapi import APIRouter, Depends, HTTPException, Header
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from uuid import UUID
import logging
from ..core.database import get_db
from ..services.recipe_service import RecipeService
from ..schemas.recipes import (
RecipeQualityConfiguration,
RecipeQualityConfigurationUpdate
)
from shared.routing import RouteBuilder, RouteCategory
from shared.auth.access_control import require_user_role
route_builder = RouteBuilder('recipes')
logger = logging.getLogger(__name__)
router = APIRouter(tags=["recipe-quality-configs"])
def get_user_id(x_user_id: str = Header(...)) -> UUID:
"""Extract user ID from header"""
try:
return UUID(x_user_id)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid user ID format")
@router.get(
route_builder.build_custom_route(RouteCategory.BASE, ["{recipe_id}", "quality-configuration"]),
response_model=RecipeQualityConfiguration
)
async def get_recipe_quality_configuration(
tenant_id: UUID,
recipe_id: UUID,
db: AsyncSession = Depends(get_db)
):
"""Get quality configuration for a specific recipe"""
try:
recipe_service = RecipeService(db)
recipe = await recipe_service.get_recipe(tenant_id, recipe_id)
if not recipe:
raise HTTPException(status_code=404, detail="Recipe not found")
quality_config = recipe.get("quality_check_configuration")
if not quality_config:
quality_config = {
"stages": {},
"overall_quality_threshold": 7.0,
"critical_stage_blocking": True,
"auto_create_quality_checks": True,
"quality_manager_approval_required": False
}
return quality_config
except HTTPException:
raise
except Exception as e:
logger.error(f"Error getting recipe quality configuration: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.put(
route_builder.build_custom_route(RouteCategory.BASE, ["{recipe_id}", "quality-configuration"]),
response_model=RecipeQualityConfiguration
)
@require_user_role(['admin', 'owner', 'member'])
async def update_recipe_quality_configuration(
tenant_id: UUID,
recipe_id: UUID,
quality_config: RecipeQualityConfigurationUpdate,
user_id: UUID = Depends(get_user_id),
db: AsyncSession = Depends(get_db)
):
"""Update quality configuration for a specific recipe"""
try:
recipe_service = RecipeService(db)
recipe = await recipe_service.get_recipe(tenant_id, recipe_id)
if not recipe:
raise HTTPException(status_code=404, detail="Recipe not found")
updated_recipe = await recipe_service.update_recipe_quality_configuration(
tenant_id, recipe_id, quality_config.dict(exclude_unset=True), user_id
)
return updated_recipe["quality_check_configuration"]
except HTTPException:
raise
except Exception as e:
logger.error(f"Error updating recipe quality configuration: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.post(
route_builder.build_custom_route(RouteCategory.BASE, ["{recipe_id}", "quality-configuration", "stages", "{stage}", "templates"])
)
@require_user_role(['admin', 'owner', 'member'])
async def add_quality_templates_to_stage(
tenant_id: UUID,
recipe_id: UUID,
stage: str,
template_ids: List[UUID],
user_id: UUID = Depends(get_user_id),
db: AsyncSession = Depends(get_db)
):
"""Add quality templates to a specific recipe stage"""
try:
recipe_service = RecipeService(db)
recipe = await recipe_service.get_recipe(tenant_id, recipe_id)
if not recipe:
raise HTTPException(status_code=404, detail="Recipe not found")
await recipe_service.add_quality_templates_to_stage(
tenant_id, recipe_id, stage, template_ids, user_id
)
return {"message": f"Added {len(template_ids)} templates to {stage} stage"}
except HTTPException:
raise
except Exception as e:
logger.error(f"Error adding quality templates to recipe stage: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.delete(
route_builder.build_custom_route(RouteCategory.BASE, ["{recipe_id}", "quality-configuration", "stages", "{stage}", "templates", "{template_id}"])
)
@require_user_role(['admin', 'owner'])
async def remove_quality_template_from_stage(
tenant_id: UUID,
recipe_id: UUID,
stage: str,
template_id: UUID,
user_id: UUID = Depends(get_user_id),
db: AsyncSession = Depends(get_db)
):
"""Remove a quality template from a specific recipe stage"""
try:
recipe_service = RecipeService(db)
recipe = await recipe_service.get_recipe(tenant_id, recipe_id)
if not recipe:
raise HTTPException(status_code=404, detail="Recipe not found")
await recipe_service.remove_quality_template_from_stage(
tenant_id, recipe_id, stage, template_id, user_id
)
return {"message": f"Removed template from {stage} stage"}
except HTTPException:
raise
except Exception as e:
logger.error(f"Error removing quality template from recipe stage: {e}")
raise HTTPException(status_code=500, detail="Internal server error")