diff --git a/README.md b/README.md index c7cc8f1..6b9278e 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,176 @@ -# 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 +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 -## Database Design +```bash +# Avvia API server +python -m uvicorn api.main:app --reload --port 8000 -### Filosofia di Semplificazione +# Avvia interfaccia web (in un altro terminale) +python gui/main.py +``` -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", + "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 @@ -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 +- **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 -#### 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. +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 -**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 \ No newline at end of file +- Email: [your-email@example.com] +- Project Link: [repository-url] \ No newline at end of file