You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Matteo Benedetto fb7fb14bcc docs: Update README with detailed installation, setup instructions, and architectural overview 7 months ago
admin-webgui feat: Implement admin web GUI with authentication, dashboard, and pietanze management 7 months ago
api feat: Implement admin web GUI with authentication, dashboard, and pietanze management 7 months ago
.gitignore feat: Refactor API structure and implement core functionalities 7 months ago
README.md docs: Update README with detailed installation, setup instructions, and architectural overview 7 months ago
compose.yaml feat: Update configuration, enhance authentication, and improve database management with Italian localization 7 months ago
requirements.txt feat: Update configuration, enhance authentication, and improve database management with Italian localization 7 months ago
schema.sql feat: Refactor API structure and implement core functionalities 7 months ago
setup_db.py feat: Update configuration, enhance authentication, and improve database management with Italian localization 7 months ago

README.md

Sistema di Prenotazione Mensa

Abstract

Il sistema di prenotazione mensa è una piattaforma web-based sviluppata con FastAPI e PostgreSQL a livello backend e NiceGUI per le interfacce fullstack, che consente agli utenti di prenotare pasti giornalieri. L'architettura è basata su un'API RESTful con autenticazione JWT, garantendo sicurezza e scalabilità. Il sistema gestisce tre entità principali interconnesse: prenotazioni, pasti e pietanze, utilizzando campi JSON per semplificare le relazioni e migliorare le performance. I dati utente sono forniti dal JWT auth bearer evitando la memorizzazione sul database di dati sensibili non necessari, sfruttando per questa funzionalità lo IAM Azure e l'account aziendale (o anche IAM self hosted Keycloak).

Stack Tecnologico

  • Backend: FastAPI (Python 3.8+)
  • Database: PostgreSQL 13+ con supporto JSON/JSONB
  • Autenticazione: JWT (JSON Web Tokens) / OpenID-Connect (provider Azure o self-hosted)
  • Frontend: NiceGUI (Python 3.9+)
  • Database Driver: asyncpg per performance ottimali
  • Validation: Pydantic models per type safety

Installazione e Setup

Prerequisiti

  • Python 3.9+
  • PostgreSQL 13+
  • pip o poetry per gestione dipendenze

Installazione

# Clona il repository
git clone <repository-url>
cd simple-mensa

# Installa dipendenze
pip install -r requirements.txt

# Configura database PostgreSQL
createdb simple_mensa

# Applica migrazioni database
python -m alembic upgrade head

# Configura variabili ambiente
cp .env.example .env
# Edita .env con le tue configurazioni

Configurazione

Configura le seguenti variabili ambiente nel file .env:

DATABASE_URL=postgresql://user:password@localhost/simple_mensa
JWT_SECRET_KEY=your-secret-key
JWT_ALGORITHM=HS256
AZURE_CLIENT_ID=your-azure-client-id  # Se si usa Azure AD
KEYCLOAK_URL=your-keycloak-url        # Se si usa Keycloak

Avvio

# Avvia API server
python -m uvicorn api.main:app --reload --port 8000

# Avvia interfaccia web (in un altro terminale)
python gui/main.py

Architettura del Sistema

Database Design

Filosofia di Semplificazione

Il database è stato progettato seguendo una filosofia di massima semplificazione, riducendo la complessità relazionale tradizionale attraverso l'uso strategico di campi JSONB di PostgreSQL al posto di tabelle intermedie per le relazioni N a N. Questa scelta progettuale offre diversi vantaggi:

  • Riduzione delle JOIN: Eliminazione di tabelle di associazione complesse
  • Flessibilità: Strutture dati dinamiche per allergeni, turni e selezioni delle pietanze
  • Performance: Meno query multiple per operazioni comuni
  • Manutenibilità: Schema più leggibile e modificabile

Struttura delle Tabelle

Tabella pietanze
CREATE TABLE pietanze (
    id SERIAL PRIMARY KEY,
    nome VARCHAR(255) NOT NULL,
    descrizione TEXT,
    allergeni JSONB,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
Tabella pasti
CREATE TABLE pasti (
    id SERIAL PRIMARY KEY,
    data DATE NOT NULL,
    tipo_pasto VARCHAR(50) NOT NULL,
    portate JSONB NOT NULL,
    turni JSONB NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(data, tipo_pasto)
);
Tabella prenotazioni
CREATE TABLE prenotazioni (
    id SERIAL PRIMARY KEY,
    user_id VARCHAR(255) NOT NULL,
    pasto_id INTEGER REFERENCES pasti(id),
    turno TIME NOT NULL,
    pietanze_selezionate JSONB NOT NULL,
    stato VARCHAR(50) DEFAULT 'attiva',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

API Documentation

Endpoints Pietanze

GET /api/pietanze/

Ottieni lista delle pietanze con filtri opzionali.

Query Parameters:

  • skip: Paginazione (default: 0)
  • limit: Numero elementi (default: 20, max: 1000)
  • search: Ricerca in nome e descrizione
  • allergeni: Filtro allergeni (separati da virgola)

Response:

[
    {
        "id": 1,
        "nome": "Pasta al pomodoro",
        "descrizione": "Pasta con salsa di pomodoro fresco",
        "allergeni": ["glutine"],
        "created_at": "2024-01-01T12:00:00Z",
        "updated_at": "2024-01-01T12:00:00Z"
    }
]

POST /api/pietanze/

Crea nuova pietanza (solo amministratori).

Request Body:

{
    "nome": "Risotto ai funghi",
    "descrizione": "Risotto cremoso con funghi porcini",
    "allergeni": ["latticini"]
}

PUT /api/pietanze/{pietanza_id}

Aggiorna pietanza esistente (solo amministratori).

DELETE /api/pietanze/{pietanza_id}

Elimina pietanza (solo amministratori).

Autenticazione

Tutte le operazioni di modifica richiedono autenticazione JWT:

Authorization: Bearer <jwt-token>

Flussi Operativi

Flusso di Creazione Menu Giornaliero

  1. Inserimento Pietanze: Caricamento delle pietanze disponibili per il giorno
  2. Composizione Pasto: Associazione pietanze alle portate tramite JSON
  3. Configurazione Turni: Definizione orari e capacità massima per turno
  4. Attivazione: Abilitazione delle prenotazioni per gli utenti

Flusso di Prenotazione Utente

  1. Autenticazione: Verifica JWT e estrazione user_id
  2. Visualizzazione Menu: Recupero pasti disponibili per data
  3. Selezione Pietanze: Scelta pietanze per ogni portata disponibile
  4. Validazione: Controllo disponibilità e limiti di prenotazione
  5. Conferma: Creazione record prenotazione con stato 'attiva'

Flusso di Servizio Mensa

  1. Consultazione Prenotazioni: Visualizzazione prenotazioni per turno
  2. Erogazione Pasto: Aggiornamento stato da 'attiva' a 'servita', 'pagata', 'completata'
  3. Monitoraggio: Tracking utilizzo e disponibilità residua

Scelte Architetturali

Principio di Separazione delle Responsabilità

La logica di business complessa rimane interamente gestita a livello API (FastAPI) piuttosto che essere delegata al database, garantendo:

  • Coerenza Architetturale: FastAPI come orchestratore centrale
  • Manutenibilità e Testabilità: Funzioni Python facilmente testabili
  • Flessibilità di Sviluppo: Evoluzione rapida senza modifiche al schema

Scelta di asyncpg vs ORM

Il sistema utilizza asyncpg come driver database per:

  • Ottimizzazione Nativa PostgreSQL: Sfruttamento completo delle funzionalità JSONB
  • Performance Async Native: Performance superiori nell'ecosistema async/await
  • Controllo Granulare: Query SQL dirette per operazioni JSONB complesse
  • Semplicità Architetturale: Overhead ridotto per tre tabelle principali

Testing

# Esegui test unitari
python -m pytest tests/

# Test con coverage
python -m pytest --cov=api tests/

# Test di integrazione
python -m pytest tests/integration/

Deployment

Docker

# Build immagine
docker build -t simple-mensa .

# Run con docker-compose
docker-compose up -d

Variabili Ambiente di Produzione

  • DATABASE_URL: URL connessione PostgreSQL
  • JWT_SECRET_KEY: Chiave segreta per JWT
  • LOG_LEVEL: Livello di logging (INFO, DEBUG, ERROR)
  • CORS_ORIGINS: Domini autorizzati per CORS

Contributi

  1. Fork del repository
  2. Crea feature branch (git checkout -b feature/AmazingFeature)
  3. Commit delle modifiche (git commit -m 'Add some AmazingFeature')
  4. Push al branch (git push origin feature/AmazingFeature)
  5. Apri Pull Request

Licenza

Distribuito sotto licenza MIT. Vedi LICENSE per maggiori informazioni.

Contatti