Files
simple-mensa/api/models/pasti.py
T
Matteo Benedetto d592e0f32b feat: Refactor API structure and implement core functionalities
- Updated requirements to include asyncpg, pyyaml, aiofiles, and httpx.
- Modified schema.sql to add 'tipo_pasto' column in 'pasti' table.
- Created .gitignore file to exclude unnecessary files and directories.
- Added README.md for API implementation details and directory structure.
- Introduced config.yaml for centralized configuration management.
- Implemented core modules for database management, authentication, and exception handling.
- Developed models for 'pietanze', 'pasti', and 'prenotazioni' with validation.
- Created routes for CRUD operations on 'pietanze' with pagination and filtering.
- Established logging and error handling mechanisms throughout the application.
- Set up FastAPI application with CORS and health check endpoint.
2025-06-05 18:31:36 +02:00

102 lines
4.0 KiB
Python

from pydantic import BaseModel, Field, validator
from typing import List, Optional, Dict, Any
from datetime import datetime, date
from enum import Enum
class TipoPasto(str, Enum):
pranzo = "pranzo"
cena = "cena"
class PastoBase(BaseModel):
data_pasto: date
tipo_pasto: TipoPasto = TipoPasto.pranzo
portate: Optional[Dict[str, Dict[int, int]]] = Field(
default_factory=dict,
description="Portate structure: {'primo': {pietanza_id: max_prenotazioni}}"
)
turni: Optional[Dict[str, int]] = Field(
default_factory=dict,
description="Turni structure: {'12:45': max_posti}"
)
disponibile: bool = True
@validator('portate')
def validate_portate(cls, v):
if v is None:
return {}
# Validate structure: each portata should have pietanza_id -> max_count mapping
valid_portate = ['primo', 'secondo', 'contorno', 'dolce', 'frutta']
for portata, pietanze in v.items():
if portata not in valid_portate:
raise ValueError(f"Portata non valida: {portata}")
if not isinstance(pietanze, dict):
raise ValueError(f"Pietanze per {portata} deve essere un dizionario")
for pietanza_id, max_count in pietanze.items():
if not isinstance(int(pietanza_id), int) or int(pietanza_id) <= 0:
raise ValueError(f"ID pietanza non valido: {pietanza_id}")
if not isinstance(max_count, int) or max_count < 0:
raise ValueError(f"Numero massimo prenotazioni non valido per pietanza {pietanza_id}")
return v
@validator('turni')
def validate_turni(cls, v):
if v is None:
return {}
# Validate time format and capacity
import re
time_pattern = re.compile(r'^([01]\d|2[0-3]):([0-5]\d)$')
for turno, capacity in v.items():
if not time_pattern.match(turno):
raise ValueError(f"Formato orario non valido: {turno}. Usare HH:MM")
if not isinstance(capacity, int) or capacity < 0:
raise ValueError(f"Capacità non valida per turno {turno}: {capacity}")
return v
class PastoCreate(PastoBase):
pass
class PastoUpdate(BaseModel):
tipo_pasto: Optional[TipoPasto] = None
portate: Optional[Dict[str, Dict[int, int]]] = None
turni: Optional[Dict[str, int]] = None
disponibile: Optional[bool] = None
# Same validators as PastoBase for optional fields
@validator('portate')
def validate_portate(cls, v):
if v is None:
return v
valid_portate = ['primo', 'secondo', 'contorno', 'dolce', 'frutta']
for portata, pietanze in v.items():
if portata not in valid_portate:
raise ValueError(f"Portata non valida: {portata}")
if not isinstance(pietanze, dict):
raise ValueError(f"Pietanze per {portata} deve essere un dizionario")
for pietanza_id, max_count in pietanze.items():
if not isinstance(int(pietanza_id), int) or int(pietanza_id) <= 0:
raise ValueError(f"ID pietanza non valido: {pietanza_id}")
if not isinstance(max_count, int) or max_count < 0:
raise ValueError(f"Numero massimo prenotazioni non valido per pietanza {pietanza_id}")
return v
@validator('turni')
def validate_turni(cls, v):
if v is None:
return v
import re
time_pattern = re.compile(r'^([01]\d|2[0-3]):([0-5]\d)$')
for turno, capacity in v.items():
if not time_pattern.match(turno):
raise ValueError(f"Formato orario non valido: {turno}. Usare HH:MM")
if not isinstance(capacity, int) or capacity < 0:
raise ValueError(f"Capacità non valida per turno {turno}: {capacity}")
return v
class PastoResponse(PastoBase):
id: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True