# Sistema di Prenotazione Mensa - Documentazione Tecnica
# 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 tr entità principali interconnesse: prenotazioni, pasti e pietanze, utilizzando campi JSON per semplificare le relazioni e migliorare le erformance. I dati utente sono forniti dal JWT auth bearer evittando 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)
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).
## Architettura del Sistema
### Stack Tecnologico
## 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)
- **HMI**: webgui fullstack NiceGUI (Python 3.9+)
- **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 <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`:
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. Contestalmente alla semplicità dello scheme e alle potenti capacità di manipolazione di dati strutturati JSON di postgresql, questa scelta progettuale offre diversi vantaggi:
## 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`
Gestisce le singole pietanze disponibili con:
- Informazioni base (nome, descrizione)
- Gestione allergeni tramite array JSON
- Controllo disponibilità e limiti di prenotazione
#### Tabella `pasti`
Rappresenta i menu giornalieri con:
- **Portate JSONB**: Organizzazione flessibile delle pietanze per tipologia indicando la disponibilità massima di ciascuna
- **Turni JSONB**: Gestione dinamica degli orari e capacità (`{"12:45": 100, "13:30": 100}`)
- Vincolo di unicità per data e tipo pasto
#### Tabella `prenotazioni`
Collega utenti e pasti con:
- Riferimento user_id estratto da JWT
- **Pietanze selezionate JSONB**: Array delle scelte dell'utente
- Gestione stati del ciclo di vita della prenotazione
#### 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",
Tutte le operazioni di modifica richiedono autenticazione JWT:
```bash
Authorization: Bearer <jwt-token>
```
## Flussi Operativi
@ -61,54 +189,73 @@ Collega utenti e pasti con:
### Flusso di Servizio Mensa
1. **Consultazione Prenotazioni**: Visualizzazione prenotazioni per turno
2. **Erogazione Pasto**: Aggiornamento stato da 'attiva', 'servita', 'pagata', 'completata'
2. **Erogazione Pasto**: Aggiornamento stato da 'attiva' a 'servita', 'pagata', 'completata'
3. **Monitoraggio**: Tracking utilizzo e disponibilità residua
### Flusso di Gestione Disponibilità
1. **Controllo Automatico**: Verifica limiti pietanze e turni
2. **Aggiornamento Dinamico**: Modifica disponibilità in tempo reale
3. **Notifiche**: Gestione comunicazioni per esaurimento posti
4. **Chiusura Prenotazioni**: Disabilitazione automatica al raggiungimento limiti
## Scelte Architetturali: Logica di Business
## Scelte Architetturali
### Principio di Separazione delle Responsabilità
In linea con la filosofia di semplificazione adottata per il design del database, **la logica di business complessa rimane interamente gestita a livello API (FastAPI)** piuttosto che essere delegata al database tramite stored procedures o funzioni PostgreSQL.
La logica di business complessa rimane interamente gestita a livello API (FastAPI) piuttosto che essere delegata al database, garantendo:
#### Motivazioni della Scelta
- **Coerenza Architetturale**: FastAPI come orchestratore centrale
- **Manutenibilità e Testabilità**: Funzioni Python facilmente testabili
- **Flessibilità di Sviluppo**: Evoluzione rapida senza modifiche al schema
**Coerenza Architetturale**: Il sistema è progettato attorno a FastAPI come orchestratore centrale. Mantenere la logica di business nell'API garantisce un'architettura coerente e predicibile.
### Scelta di asyncpg vs ORM
**Manutenibilità e Testabilità**: Le funzioni Python sono intrinsecamente più facili da testare, debuggare e modificare rispetto alle stored procedures. Questo si allinea con l'approccio DevOps moderno e l'integrazione continua.
Il sistema utilizza **asyncpg** come driver database per:
**Flessibilità di Sviluppo**: La gestione della disponibilità, dei limiti di prenotazione e delle validazioni può evolvere rapidamente senza modifiche al schema database.
- **Ottimizzazione Nativa PostgreSQL**: Sfruttamento completo delle funzionalità JSONB
- **Controllo Granulare**: Query SQL dirette per operazioni JSONB complesse
- **Semplicità Architetturale**: Overhead ridotto per tre tabelle principali
#### Implementazione delle Verifiche di Disponibilità
## Testing
Le operazioni critiche come la verifica di disponibilità posti in un turno o di una pietanza vengono gestite tramite:
- **Query atomiche** per il recupero dati
- **Validazioni Python** per la logica di business
- **Transazioni asyncpg** per garantire consistenza
- **Pattern async/await** per performance ottimali
```bash
# Esegui test unitari
python -m pytest tests/
### Scelta di asyncpg vs ORM
# 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
```
Il sistema utilizza **asyncpg** come driver database principale invece di un ORM tradizionale come SQLAlchemy per diverse ragioni strategiche:
### Variabili Ambiente di Produzione
#### Motivazioni Tecniche
- `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
**Ottimizzazione Nativa PostgreSQL**: La progettazione è strettamente legata alle funzionalità specifiche di PostgreSQL (JSONB, operatori JSON, funzioni aggregate native). Asyncpg consente di sfruttare al massimo queste capacità senza astrazioni intermedie.
## Contributi
**Performance Async Native**: Asyncpg è progettato specificamente per l'ecosistema async/await di Python, offrendo performance superiori rispetto agli adapter asincroni degli ORM tradizionali.
3. Commit delle modifiche (`git commit -m 'Add some AmazingFeature'`)
4. Push al branch (`git push origin feature/AmazingFeature`)
5. Apri Pull Request
**Controllo Granulare**: Le query SQL dirette permettono un controllo preciso delle operazioni JSONB, essenziali per la gestione delle portate, turni e selezioni pietanze.
## Licenza
**Semplicità Architetturale**: Con solo tre tabelle e logica di business in Python, l'overhead di un ORM completo risulterebbe sproporzionato rispetto ai benefici.
Distribuito sotto licenza MIT. Vedi `LICENSE` per maggiori informazioni.
#### Implementazione Pratica
## Contatti
- **Query ottimizzate** per operazioni JSONB specifiche
- **Pool di connessioni** gestito nativamente da asyncpg
- **Transazioni esplicite** per operazioni critiche di prenotazione
- **Prepared statements** per query ripetitive ad alta frequenza