# 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 ```bash # Clona il repository git clone 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`: ```bash 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 ```bash # 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` ```sql 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` ```sql 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` ```sql 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:** ```json [ { "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:** ```json { "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: ```bash Authorization: Bearer ``` ## 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 ```bash # 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 ```bash # 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 - Email: [your-email@example.com] - Project Link: [repository-url]