"""Pydantic schemas for Measurement operations.""" from datetime import datetime from typing import Optional from pydantic import BaseModel, ConfigDict, Field class MeasurementCreate(BaseModel): """Schema for creating a single measurement.""" subtask_id: int version_id: int value: float lot_number: Optional[str] = Field(None, max_length=100) serial_number: Optional[str] = Field(None, max_length=100) input_method: str = Field("manual", pattern="^(usb_caliper|manual)$") class MeasurementBatchCreate(BaseModel): """Schema for creating multiple measurements at once.""" measurements: list[MeasurementCreate] class MeasurementResponse(BaseModel): """Schema for measurement response.""" model_config = ConfigDict(from_attributes=True) id: int subtask_id: int version_id: int measured_by: int value: float pass_fail: str deviation: Optional[float] = None lot_number: Optional[str] = None serial_number: Optional[str] = None input_method: str measured_at: datetime synced_to_csv: bool class MeasurementListResponse(BaseModel): """Schema for paginated measurement list.""" items: list[MeasurementResponse] total: int page: int per_page: int pages: int class MeasurementQuery(BaseModel): """Schema for measurement query filters.""" recipe_id: Optional[int] = None version_id: Optional[int] = None subtask_id: Optional[int] = None measured_by: Optional[int] = None lot_number: Optional[str] = None serial_number: Optional[str] = None date_from: Optional[datetime] = None date_to: Optional[datetime] = None pass_fail: Optional[str] = Field(None, pattern="^(pass|warning|fail)$") page: int = Field(1, ge=1) per_page: int = Field(50, ge=1, le=500)