fix(vision): execute controlla task_type, versione, ricetta attiva, produzione (#38.7)

execute_task rifiuta 422 se il task non è camera_measure, 409 se la
versione non è corrente o la ricetta non è attiva; production_run_id,
quando presente, è validato con measurement_service.validate_run_for_version
(stessa regola di una lettura manuale). Router: lot_number/serial_number
max_length=100, production_run_id gt=0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 22:41:22 +02:00
parent c8caf40af9
commit 1c5292d1e0
3 changed files with 257 additions and 3 deletions
+30
View File
@@ -17,6 +17,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from src.backend.config import settings
from src.backend.models.orm.measurement import Measurement
from src.backend.models.orm.recipe import RecipeVersion
from src.backend.models.orm.task import RecipeSubtask, RecipeTask
from src.backend.models.orm.vision import VisionReferenceImage, VisionResult
from src.backend.services import measurement_service
@@ -132,6 +133,35 @@ async def execute_task(
serial_number: str | None = None,
production_run_id: int | None = None,
) -> tuple[VisionResult, list[Measurement]]:
if task.task_type != "camera_measure":
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
detail=f"task type {task.task_type!r} is not a camera measurement",
)
version = (await db.execute(
select(RecipeVersion).where(RecipeVersion.id == version_id)
)).scalar_one_or_none()
if version is None or not version.is_current:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="this task's recipe version is no longer current",
)
recipe = await measurement_service.recipe_of_version(db, version_id)
if recipe is None or not recipe.active:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="this recipe is not active",
)
if production_run_id is not None:
# 404 if the run does not exist, 422 if it belongs to another recipe,
# 409 if it is closed or paused - same rule a manual reading follows.
await measurement_service.validate_run_for_version(
db, production_run_id, version_id,
)
if not task.vision_json:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,