Add quality template logic

This commit is contained in:
Urtzi Alfaro
2025-09-24 16:42:23 +02:00
parent 474d7176bf
commit 2de1e6ce40
11 changed files with 450 additions and 228 deletions

View File

@@ -22,7 +22,6 @@ from app.schemas.production import (
ProductionStatusEnum
)
from app.core.config import settings
from .quality_templates import router as quality_templates_router
logger = structlog.get_logger()
@@ -1096,6 +1095,211 @@ async def get_yield_metrics(
return metrics
except Exception as e:
logger.error("Error getting yield metrics",
logger.error("Error getting yield metrics",
error=str(e), tenant_id=str(tenant_id))
raise HTTPException(status_code=500, detail="Failed to get yield metrics")
raise HTTPException(status_code=500, detail="Failed to get yield metrics")
# ================================================================
# QUALITY TEMPLATES ENDPOINTS
# ================================================================
from app.repositories.quality_template_repository import QualityTemplateRepository
from app.schemas.quality_templates import (
QualityCheckTemplateCreate,
QualityCheckTemplateUpdate,
QualityCheckTemplateResponse,
QualityCheckTemplateList
)
@router.get("/tenants/{tenant_id}/production/quality-templates", response_model=QualityCheckTemplateList)
async def get_quality_templates(
tenant_id: UUID = Path(...),
stage: Optional[str] = Query(None, description="Filter by process stage"),
check_type: Optional[str] = Query(None, description="Filter by check type"),
is_active: Optional[bool] = Query(True, description="Filter by active status"),
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1, le=1000),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Get quality check templates for tenant"""
try:
repo = QualityTemplateRepository(db)
# Convert stage string to ProcessStage enum if provided
stage_enum = None
if stage:
try:
stage_enum = ProcessStage(stage)
except ValueError:
raise HTTPException(status_code=400, detail=f"Invalid stage: {stage}")
templates, total = await repo.get_templates_by_tenant(
tenant_id=str(tenant_id),
stage=stage_enum,
check_type=check_type,
is_active=is_active,
skip=skip,
limit=limit
)
return QualityCheckTemplateList(
templates=[QualityCheckTemplateResponse.from_orm(t) for t in templates],
total=total,
skip=skip,
limit=limit
)
except HTTPException:
raise
except Exception as e:
logger.error("Error getting quality templates",
error=str(e), tenant_id=str(tenant_id))
raise HTTPException(status_code=500, detail="Failed to get quality templates")
@router.post("/tenants/{tenant_id}/production/quality-templates", response_model=QualityCheckTemplateResponse)
async def create_quality_template(
template_data: QualityCheckTemplateCreate,
tenant_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Create a new quality check template"""
try:
repo = QualityTemplateRepository(db)
# Add tenant_id to the template data
create_data = template_data.dict()
create_data['tenant_id'] = str(tenant_id)
template = await repo.create(create_data)
return QualityCheckTemplateResponse.from_orm(template)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error("Error creating quality template",
error=str(e), tenant_id=str(tenant_id))
raise HTTPException(status_code=500, detail="Failed to create quality template")
@router.get("/tenants/{tenant_id}/production/quality-templates/{template_id}", response_model=QualityCheckTemplateResponse)
async def get_quality_template(
tenant_id: UUID = Path(...),
template_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Get a specific quality check template"""
try:
repo = QualityTemplateRepository(db)
template = await repo.get_by_tenant_and_id(str(tenant_id), template_id)
if not template:
raise HTTPException(status_code=404, detail="Quality template not found")
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except Exception as e:
logger.error("Error getting quality template",
error=str(e), tenant_id=str(tenant_id), template_id=str(template_id))
raise HTTPException(status_code=500, detail="Failed to get quality template")
@router.put("/tenants/{tenant_id}/production/quality-templates/{template_id}", response_model=QualityCheckTemplateResponse)
async def update_quality_template(
template_data: QualityCheckTemplateUpdate,
tenant_id: UUID = Path(...),
template_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Update a quality check template"""
try:
repo = QualityTemplateRepository(db)
# First check if template exists and belongs to tenant
existing = await repo.get_by_tenant_and_id(str(tenant_id), template_id)
if not existing:
raise HTTPException(status_code=404, detail="Quality template not found")
template = await repo.update(template_id, template_data.dict(exclude_unset=True))
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error("Error updating quality template",
error=str(e), tenant_id=str(tenant_id), template_id=str(template_id))
raise HTTPException(status_code=500, detail="Failed to update quality template")
@router.delete("/tenants/{tenant_id}/production/quality-templates/{template_id}")
async def delete_quality_template(
tenant_id: UUID = Path(...),
template_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Delete a quality check template"""
try:
repo = QualityTemplateRepository(db)
# First check if template exists and belongs to tenant
existing = await repo.get_by_tenant_and_id(str(tenant_id), template_id)
if not existing:
raise HTTPException(status_code=404, detail="Quality template not found")
await repo.delete(template_id)
return {"message": "Quality template deleted successfully"}
except HTTPException:
raise
except Exception as e:
logger.error("Error deleting quality template",
error=str(e), tenant_id=str(tenant_id), template_id=str(template_id))
raise HTTPException(status_code=500, detail="Failed to delete quality template")
@router.post("/tenants/{tenant_id}/production/quality-templates/{template_id}/duplicate", response_model=QualityCheckTemplateResponse)
async def duplicate_quality_template(
tenant_id: UUID = Path(...),
template_id: UUID = Path(...),
current_user: dict = Depends(get_current_user_dep),
db=Depends(get_db)
):
"""Duplicate an existing quality check template"""
try:
repo = QualityTemplateRepository(db)
# Get original template
original = await repo.get_by_tenant_and_id(str(tenant_id), template_id)
if not original:
raise HTTPException(status_code=404, detail="Quality template not found")
# Create duplicate data
duplicate_data = {
"tenant_id": original.tenant_id,
"name": f"{original.name} (Copy)",
"template_code": None, # Will be auto-generated
"check_type": original.check_type,
"category": original.category,
"description": original.description,
"instructions": original.instructions,
"criteria": original.criteria,
"is_required": original.is_required,
"is_critical": original.is_critical,
"weight": original.weight,
"min_value": original.min_value,
"max_value": original.max_value,
"unit": original.unit,
"tolerance_percentage": original.tolerance_percentage,
"applicable_stages": original.applicable_stages,
"created_by": original.created_by
}
template = await repo.create(duplicate_data)
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except Exception as e:
logger.error("Error duplicating quality template",
error=str(e), tenant_id=str(tenant_id), template_id=str(template_id))
raise HTTPException(status_code=500, detail="Failed to duplicate quality template")

View File

@@ -1,174 +0,0 @@
# services/production/app/api/quality_templates.py
"""
Quality Check Template API endpoints for production service
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from uuid import UUID
from ..core.database import get_db
from ..models.production import QualityCheckTemplate, ProcessStage
from ..services.quality_template_service import QualityTemplateService
from ..schemas.quality_templates import (
QualityCheckTemplateCreate,
QualityCheckTemplateUpdate,
QualityCheckTemplateResponse,
QualityCheckTemplateList
)
from shared.auth.tenant_access import get_current_tenant_id
router = APIRouter(prefix="/quality-templates", tags=["quality-templates"])
@router.post("", response_model=QualityCheckTemplateResponse, status_code=status.HTTP_201_CREATED)
async def create_quality_template(
template_data: QualityCheckTemplateCreate,
tenant_id: str = Depends(get_current_tenant_id),
db: Session = Depends(get_db)
):
"""Create a new quality check template"""
try:
service = QualityTemplateService(db)
template = await service.create_template(tenant_id, template_data)
return QualityCheckTemplateResponse.from_orm(template)
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.get("", response_model=QualityCheckTemplateList)
async def get_quality_templates(
tenant_id: str = Depends(get_current_tenant_id),
stage: Optional[ProcessStage] = Query(None, description="Filter by process stage"),
check_type: Optional[str] = Query(None, description="Filter by check type"),
is_active: Optional[bool] = Query(True, description="Filter by active status"),
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1, le=1000),
db: Session = Depends(get_db)
):
"""Get quality check templates for tenant"""
try:
service = QualityTemplateService(db)
templates, total = await service.get_templates(
tenant_id=tenant_id,
stage=stage,
check_type=check_type,
is_active=is_active,
skip=skip,
limit=limit
)
return QualityCheckTemplateList(
templates=[QualityCheckTemplateResponse.from_orm(t) for t in templates],
total=total,
skip=skip,
limit=limit
)
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.get("/{template_id}", response_model=QualityCheckTemplateResponse)
async def get_quality_template(
template_id: UUID,
tenant_id: str = Depends(get_current_tenant_id),
db: Session = Depends(get_db)
):
"""Get a specific quality check template"""
try:
service = QualityTemplateService(db)
template = await service.get_template(tenant_id, template_id)
if not template:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.put("/{template_id}", response_model=QualityCheckTemplateResponse)
async def update_quality_template(
template_id: UUID,
template_data: QualityCheckTemplateUpdate,
tenant_id: str = Depends(get_current_tenant_id),
db: Session = Depends(get_db)
):
"""Update a quality check template"""
try:
service = QualityTemplateService(db)
template = await service.update_template(tenant_id, template_id, template_data)
if not template:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_quality_template(
template_id: UUID,
tenant_id: str = Depends(get_current_tenant_id),
db: Session = Depends(get_db)
):
"""Delete a quality check template"""
try:
service = QualityTemplateService(db)
success = await service.delete_template(tenant_id, template_id)
if not success:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.get("/stages/{stage}", response_model=QualityCheckTemplateList)
async def get_templates_for_stage(
stage: ProcessStage,
tenant_id: str = Depends(get_current_tenant_id),
is_active: Optional[bool] = Query(True, description="Filter by active status"),
db: Session = Depends(get_db)
):
"""Get quality check templates applicable to a specific process stage"""
try:
service = QualityTemplateService(db)
templates = await service.get_templates_for_stage(tenant_id, stage, is_active)
return QualityCheckTemplateList(
templates=[QualityCheckTemplateResponse.from_orm(t) for t in templates],
total=len(templates),
skip=0,
limit=len(templates)
)
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
@router.post("/{template_id}/duplicate", response_model=QualityCheckTemplateResponse, status_code=status.HTTP_201_CREATED)
async def duplicate_quality_template(
template_id: UUID,
tenant_id: str = Depends(get_current_tenant_id),
db: Session = Depends(get_db)
):
"""Duplicate an existing quality check template"""
try:
service = QualityTemplateService(db)
template = await service.duplicate_template(tenant_id, template_id)
if not template:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
return QualityCheckTemplateResponse.from_orm(template)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))