diff --git a/server/schemas/station.py b/server/schemas/station.py new file mode 100644 index 0000000..d44e870 --- /dev/null +++ b/server/schemas/station.py @@ -0,0 +1,57 @@ +"""Pydantic schemas for Station and StationRecipeAssignment.""" +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field + + +class StationCreate(BaseModel): + code: str = Field(..., min_length=1, max_length=100) + name: str = Field(..., min_length=1, max_length=255) + location: Optional[str] = Field(default=None, max_length=255) + notes: Optional[str] = None + active: bool = True + + +class StationUpdate(BaseModel): + name: Optional[str] = Field(default=None, min_length=1, max_length=255) + location: Optional[str] = Field(default=None, max_length=255) + notes: Optional[str] = None + active: Optional[bool] = None + + +class StationResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int + code: str + name: str + location: Optional[str] + notes: Optional[str] + active: bool + created_by: int + created_at: datetime + + +class StationRecipeAssignmentCreate(BaseModel): + recipe_id: int = Field(..., gt=0) + + +class StationRecipeAssignmentResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int + station_id: int + recipe_id: int + assigned_by: int + assigned_at: datetime + + +class _RecipeSummary(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int + code: str + name: str + active: bool + + +class StationWithRecipesResponse(StationResponse): + recipes: list[_RecipeSummary] = Field(default_factory=list) diff --git a/server/tests/test_station_schemas.py b/server/tests/test_station_schemas.py new file mode 100644 index 0000000..5b75763 --- /dev/null +++ b/server/tests/test_station_schemas.py @@ -0,0 +1,35 @@ +"""Tests for Station Pydantic schemas.""" +import pytest +from pydantic import ValidationError + +from schemas.station import ( + StationCreate, StationUpdate, StationResponse, + StationRecipeAssignmentCreate, StationRecipeAssignmentResponse, + StationWithRecipesResponse, +) + + +def test_station_create_valid(): + data = StationCreate(code="ST-001", name="Linea 1", location="Reparto Nord") + assert data.code == "ST-001" + assert data.active is True + + +def test_station_create_rejects_empty_code(): + with pytest.raises(ValidationError): + StationCreate(code="", name="X") + + +def test_station_create_rejects_too_long_code(): + with pytest.raises(ValidationError): + StationCreate(code="A" * 101, name="X") + + +def test_station_update_all_optional(): + data = StationUpdate() + assert data.name is None + + +def test_station_assignment_create(): + data = StationRecipeAssignmentCreate(recipe_id=42) + assert data.recipe_id == 42