Browse Source

docs: Update README with detailed installation, setup instructions, and architectural overview

master
Matteo Benedetto 7 months ago
parent
commit
fb7fb14bcc
  1. 265
      README.md

265
README.md

@ -1,48 +1,176 @@
# Sistema di Prenotazione Mensa - Documentazione Tecnica # Sistema di Prenotazione Mensa
## Abstract ## 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+) - **Backend**: FastAPI (Python 3.8+)
- **Database**: PostgreSQL 13+ con supporto JSON/JSONB - **Database**: PostgreSQL 13+ con supporto JSON/JSONB
- **Autenticazione**: JWT (JSON Web Tokens) / OpenID-Connect (provider Azure o self-hosted) - **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`:
```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 - **Riduzione delle JOIN**: Eliminazione di tabelle di associazione complesse
- **Flessibilità**: Strutture dati dinamiche per allergeni, turni e selezioni delle pietanze - **Flessibilità**: Strutture dati dinamiche per allergeni, turni e selezioni delle pietanze
- **Performance**: Meno query multiple per operazioni comuni - **Performance**: Meno query multiple per operazioni comuni
- **Manutenibilità**: Schema più leggibile e modificabile - **Manutenibilità**: Schema più leggibile e modificabile
### Struttura delle Tabelle #### Struttura delle Tabelle
#### Tabella `pietanze` ##### Tabella `pietanze`
Gestisce le singole pietanze disponibili con: ```sql
- Informazioni base (nome, descrizione) CREATE TABLE pietanze (
- Gestione allergeni tramite array JSON id SERIAL PRIMARY KEY,
- Controllo disponibilità e limiti di prenotazione nome VARCHAR(255) NOT NULL,
descrizione TEXT,
#### Tabella `pasti` allergeni JSONB,
Rappresenta i menu giornalieri con: created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
- **Portate JSONB**: Organizzazione flessibile delle pietanze per tipologia indicando la disponibilità massima di ciascuna updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
- **Turni JSONB**: Gestione dinamica degli orari e capacità (`{"12:45": 100, "13:30": 100}`) );
- Vincolo di unicità per data e tipo pasto ```
#### Tabella `prenotazioni` ##### Tabella `pasti`
Collega utenti e pasti con: ```sql
- Riferimento user_id estratto da JWT CREATE TABLE pasti (
- **Pietanze selezionate JSONB**: Array delle scelte dell'utente id SERIAL PRIMARY KEY,
- Gestione stati del ciclo di vita della prenotazione 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 <jwt-token>
```
## Flussi Operativi ## Flussi Operativi
@ -61,54 +189,73 @@ Collega utenti e pasti con:
### Flusso di Servizio Mensa ### Flusso di Servizio Mensa
1. **Consultazione Prenotazioni**: Visualizzazione prenotazioni per turno 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 3. **Monitoraggio**: Tracking utilizzo e disponibilità residua
### Flusso di Gestione Disponibilità ## Scelte Architetturali
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
### Principio di Separazione delle Responsabilità ### 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: ```bash
- **Query atomiche** per il recupero dati # Esegui test unitari
- **Validazioni Python** per la logica di business python -m pytest tests/
- **Transazioni asyncpg** per garantire consistenza
- **Pattern async/await** per performance ottimali
### 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 - Email: [your-email@example.com]
- **Pool di connessioni** gestito nativamente da asyncpg - Project Link: [repository-url]
- **Transazioni esplicite** per operazioni critiche di prenotazione
- **Prepared statements** per query ripetitive ad alta frequenza
Loading…
Cancel
Save