feat: Update configuration, enhance authentication, and improve database management with Italian localization

This commit is contained in:
Matteo Benedetto
2025-06-05 19:27:15 +02:00
parent d592e0f32b
commit a833ce93f8
11 changed files with 522 additions and 133 deletions
+51 -56
View File
@@ -3,25 +3,25 @@ from typing import List, Optional, Dict, Any
import json
from datetime import datetime
from ..core.database import get_database, DatabaseManager
from ..models.pietanze import PietanzaCreate, PietanzaUpdate, PietanzaResponse
from ..models.common import ErrorResponse
from ..core.auth import get_current_user, get_current_admin_user
from ..core.exceptions import PietanzaNotFoundError, DatabaseError
from core.database import get_database, DatabaseManager
from models.pietanze import PietanzaCreate, PietanzaUpdate, PietanzaResponse
from models.common import ErrorResponse
from core.auth import get_current_user, get_current_admin_user
from core.exceptions import PietanzaNotFoundError, DatabaseError
router = APIRouter(prefix="/pietanze", tags=["Pietanze"])
@router.get("/", response_model=List[PietanzaResponse])
async def list_pietanze(
skip: int = Query(0, ge=0, description="Number of items to skip"),
limit: int = Query(20, ge=1, le=100, description="Number of items to return"),
search: Optional[str] = Query(None, description="Search in nome and descrizione"),
allergeni: Optional[str] = Query(None, description="Filter by allergens (comma-separated)"),
skip: int = Query(0, ge=0, description="Numero di elementi da saltare per la paginazione"),
limit: int = Query(20, ge=1, le=100, description="Numero di elementi da restituire"),
search: Optional[str] = Query(None, description="Ricerca in nome e descrizione"),
allergeni: Optional[str] = Query(None, description="Filtra per allergeni (separati da virgola)"),
db: DatabaseManager = Depends(get_database)
):
"""Get list of available pietanze with optional filtering"""
"""Ottieni lista delle pietanze disponibili con filtri opzionali"""
try:
# Build query with filters
# Costruisci query con filtri
where_conditions = []
params = []
param_count = 0
@@ -41,12 +41,12 @@ async def list_pietanze(
if where_conditions:
where_clause = "WHERE " + " AND ".join(where_conditions)
# Count total items
# Conta il totale degli elementi
count_query = f"SELECT COUNT(*) FROM pietanze {where_clause}"
count_result = await db.execute_one(count_query, *params)
total = count_result[0] if count_result else 0
# Get items with pagination
# Ottieni elementi con paginazione
param_count += 1
limit_param = param_count
param_count += 1
@@ -77,14 +77,14 @@ async def list_pietanze(
return pietanze
except Exception as e:
raise DatabaseError(f"Failed to retrieve pietanze: {str(e)}")
raise DatabaseError(f"Errore nel recupero delle pietanze: {str(e)}")
@router.get("/{pietanza_id}", response_model=PietanzaResponse)
async def get_pietanza(
pietanza_id: int,
db: DatabaseManager = Depends(get_database)
):
"""Get specific pietanza by ID"""
"""Ottieni pietanza specifica per ID"""
try:
query = """
SELECT id, nome, descrizione, allergeni, created_at, updated_at
@@ -108,7 +108,7 @@ async def get_pietanza(
except PietanzaNotFoundError:
raise
except Exception as e:
raise DatabaseError(f"Failed to retrieve pietanza: {str(e)}")
raise DatabaseError(f"Errore nel recupero della pietanza: {str(e)}")
@router.post("/", response_model=PietanzaResponse, status_code=status.HTTP_201_CREATED)
async def create_pietanza(
@@ -116,7 +116,7 @@ async def create_pietanza(
current_user: Dict[str, Any] = Depends(get_current_admin_user),
db: DatabaseManager = Depends(get_database)
):
"""Create new pietanza (admin only)"""
"""Crea nuova pietanza (solo amministratori)"""
try:
query = """
INSERT INTO pietanze (nome, descrizione, allergeni, created_at, updated_at)
@@ -136,7 +136,7 @@ async def create_pietanza(
)
if not row:
raise DatabaseError("Failed to create pietanza")
raise DatabaseError("Errore nella creazione della pietanza")
return PietanzaResponse(
id=row['id'],
@@ -148,7 +148,7 @@ async def create_pietanza(
)
except Exception as e:
raise DatabaseError(f"Failed to create pietanza: {str(e)}")
raise DatabaseError(f"Errore nella creazione della pietanza: {str(e)}")
@router.put("/{pietanza_id}", response_model=PietanzaResponse)
async def update_pietanza(
@@ -157,14 +157,14 @@ async def update_pietanza(
current_user: Dict[str, Any] = Depends(get_current_admin_user),
db: DatabaseManager = Depends(get_database)
):
"""Update existing pietanza (admin only)"""
"""Aggiorna pietanza esistente (solo amministratori)"""
try:
# Check if pietanza exists
# Verifica se la pietanza esiste
existing = await db.execute_one("SELECT id FROM pietanze WHERE id = $1", pietanza_id)
if not existing:
raise PietanzaNotFoundError(pietanza_id)
# Build update query dynamically
# Costruisci query di aggiornamento dinamicamente
update_fields = []
params = []
param_count = 0
@@ -185,10 +185,10 @@ async def update_pietanza(
params.append(json.dumps(pietanza_update.allergeni))
if not update_fields:
# No fields to update, return current pietanza
# Nessun campo da aggiornare, restituisci pietanza corrente
return await get_pietanza(pietanza_id, db)
# Add updated_at and pietanza_id
# Aggiungi updated_at e pietanza_id
param_count += 1
update_fields.append(f"updated_at = ${param_count}")
params.append(datetime.utcnow())
@@ -217,7 +217,7 @@ async def update_pietanza(
except PietanzaNotFoundError:
raise
except Exception as e:
raise DatabaseError(f"Failed to update pietanza: {str(e)}")
raise DatabaseError(f"Errore nell'aggiornamento della pietanza: {str(e)}")
@router.delete("/{pietanza_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_pietanza(
@@ -225,41 +225,36 @@ async def delete_pietanza(
current_user: Dict[str, Any] = Depends(get_current_admin_user),
db: DatabaseManager = Depends(get_database)
):
"""Delete pietanza (admin only)"""
"""Elimina pietanza (solo amministratori)"""
try:
# Check if pietanza exists
existing = await db.execute_one("SELECT id FROM pietanze WHERE id = $1", pietanza_id)
if not existing:
# Verifica se la pietanza è associata a qualche pasto usando operatori JSONB
# Controlla se l'ID della pietanza (come stringa) appare come chiave in qualsiasi portata
pasto_check = await db.execute_one("""
SELECT COUNT(*)
FROM pasti
WHERE EXISTS (
SELECT 1
FROM jsonb_each(portate) AS p
WHERE jsonb_typeof(p.value) = 'object'
AND p.value ? $1
)
""", str(pietanza_id))
if pasto_check and pasto_check[0] > 0:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Impossibile eliminare la pietanza: è ancora associata a uno o più pasti"
)
# Elimina la pietanza e verifica se esisteva
result = await db.execute_one("DELETE FROM pietanze WHERE id = $1 RETURNING id", pietanza_id)
if not result:
raise PietanzaNotFoundError(pietanza_id)
# Delete the pietanza
result = await db.execute_command("DELETE FROM pietanze WHERE id = $1", pietanza_id)
# Check if deletion was successful
if not result or not result.endswith("1"):
raise DatabaseError("Failed to delete pietanza")
except PietanzaNotFoundError:
raise
except Exception as e:
raise DatabaseError(f"Failed to delete pietanza: {str(e)}")
@router.get("/{pietanza_id}/allergeni", response_model=List[str])
async def get_pietanza_allergeni(
pietanza_id: int,
db: DatabaseManager = Depends(get_database)
):
"""Get allergen information for specific pietanza"""
try:
query = "SELECT allergeni FROM pietanze WHERE id = $1"
row = await db.execute_one(query, pietanza_id)
if not row:
raise PietanzaNotFoundError(pietanza_id)
return row['allergeni'] or []
except PietanzaNotFoundError:
except HTTPException:
raise
except Exception as e:
raise DatabaseError(f"Failed to retrieve allergeni: {str(e)}")
raise DatabaseError(f"Errore nell'eliminazione della pietanza: {str(e)}")