From 60d21db3f24910c91049e3af8de41d9f5e1eb72a Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Thu, 5 Jun 2025 11:07:16 +0200 Subject: [PATCH] first commit --- README.md | 0 idea.md | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++ schema.sql | 34 ++++++++++ setup_db.py | 37 +++++++++++ 4 files changed, 251 insertions(+) create mode 100644 README.md create mode 100644 idea.md create mode 100644 schema.sql create mode 100644 setup_db.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/idea.md b/idea.md new file mode 100644 index 0000000..6a4199f --- /dev/null +++ b/idea.md @@ -0,0 +1,180 @@ +# Sistema di Prenotazione Mensa - Documentazione Tecnica + +## Abstract + +Il sistema di prenotazione mensa è una piattaforma web-based sviluppata con FastAPI e PostgreSQL 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 quattro entità principali interconnesse: prenotazioni, pasti, pietanze e ingredienti, utilizzando campi JSON per semplificare le relazioni e migliorare le performance. + +## Architettura del Sistema + +### Stack Tecnologico + +- **Backend**: FastAPI (Python 3.8+) +- **Database**: PostgreSQL 13+ con supporto JSON/JSONB +- **Autenticazione**: JWT (JSON Web Tokens) +- **ORM**: SQLAlchemy + +### Componenti Principali + +1. **API Layer**: Gestione endpoint REST con FastAPI +2. **Authentication Layer**: Middleware JWT per sicurezza +3. **Business Logic Layer**: Logica di prenotazione e validazione +4. **Data Access Layer**: SQLAlchemy ORM per accesso ai dati +5. **Database Layer**: PostgreSQL con schema relazionale + +## Schema Database + +### Struttura delle Tabelle + +#### 1. Tabella `pietanze` +```sql +CREATE TABLE pietanze ( + id SERIAL PRIMARY KEY, + nome VARCHAR(150) NOT NULL, + descrizione TEXT, + categoria VARCHAR(50), -- primo, secondo, contorno, dolce + prezzo DECIMAL(5,2), + disponibile BOOLEAN DEFAULT true, + ingredienti TEXT, -- Testo libero + allergeni JSONB, -- Array di allergeni: ["glutine", "lattosio", ...] + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +#### 2. Tabella `pasti` +```sql +CREATE TABLE pasti ( + id SERIAL PRIMARY KEY, + data_pasto DATE NOT NULL, + tipo_pasto VARCHAR(20) NOT NULL, -- colazione, pranzo, cena + disponibile BOOLEAN DEFAULT true, + turno VARCHAR(20) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(data_pasto, tipo_pasto) +); +``` + +#### 3. Tabella `prenotazioni` +```sql +CREATE TABLE prenotazioni ( + id SERIAL PRIMARY KEY, + user_id VARCHAR(100) NOT NULL, -- Estratto dal JWT + pasto_id INTEGER REFERENCES pasti(id) ON DELETE CASCADE, + pietanze_selezionate JSONB, -- Lista di pietanze + note TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(user_id, pasto_id) +); +``` + +## Endpoint API - Prenotazione Pasti + +### 1. Creazione di una prenotazione +**POST /api/prenotazioni** + +- **Descrizione**: Crea una nuova prenotazione per un pasto specifico. +- **Corpo della richiesta**: + ```json + { + "pasto_id": 1, + "pietanze_selezionate": [ + 2,86,89 + ], + "note": "Senza glutine" + } + ``` +- **Risposta**: + - **201 Created**: + ```json + { + "id": 42, + "user_id": "utente123", + "pasto_id": 1, + "stato": "attiva", + "pietanze_selezionate": [ + { "id": 1, "quantita": 1 }, + { "id": 3, "quantita": 2 } + ], + "note": "Senza glutine", + "created_at": "2023-10-01T12:00:00Z", + "updated_at": "2023-10-01T12:00:00Z" + } + ``` + - **400 Bad Request**: Errore di validazione o dati mancanti. + +--- + +### 2. Recupero delle prenotazioni di un utente +**GET /api/prenotazioni** + +- **Descrizione**: Recupera tutte le prenotazioni dell'utente autenticato. +- **Risposta**: + - **200 OK**: + ```json + [ + { + "id": 42, + "pasto_id": 1, + "stato": "attiva", + "pietanze_selezionate": [ + { "id": 1, "quantita": 1 }, + { "id": 3, "quantita": 2 } + ], + "note": "Senza glutine", + "created_at": "2023-10-01T12:00:00Z", + "updated_at": "2023-10-01T12:00:00Z" + } + ] + ``` + +--- + +### 3. Annullamento di una prenotazione +**PUT /api/prenotazioni/{id}/annulla** + +- **Descrizione**: Annulla una prenotazione esistente. +- **Risposta**: + - **200 OK**: + ```json + { + "id": 42, + "stato": "cancellata", + "updated_at": "2023-10-01T12:30:00Z" + } + ``` + - **404 Not Found**: Prenotazione non trovata. + +--- + +### 4. Recupero dei pasti disponibili +**GET /api/pasti** + +- **Descrizione**: Recupera i pasti disponibili per la prenotazione. +- **Parametri query**: + - `data` (opzionale): Filtra per data specifica (formato YYYY-MM-DD) + - `tipo_pasto` (opzionale): Filtra per tipo di pasto (colazione, pranzo, cena) +- **Esempi**: + - `GET /api/pasti` - Tutti i pasti disponibili + - `GET /api/pasti?data=2023-10-02` - Pasti per il 2 ottobre 2023 + - `GET /api/pasti?data=2023-10-02&tipo_pasto=pranzo` - Solo pranzi del 2 ottobre +- **Risposta**: + - **200 OK**: + ```json + [ + { + "id": 1, + "data_pasto": "2023-10-02", + "tipo_pasto": "pranzo", + "turno": "12:00-14:00", + "disponibile": true, + "posti_totali": 100, + "posti_prenotati": 20, + "pietanze_disponibili": [ + { "id": 1, "nome": "Lasagna", "prezzo": 8.50 }, + { "id": 2, "nome": "Insalata", "prezzo": 5.00 } + ] + } + ] + ``` diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..b3d566b --- /dev/null +++ b/schema.sql @@ -0,0 +1,34 @@ +CREATE TABLE pietanze ( + id SERIAL PRIMARY KEY, + nome VARCHAR(150) NOT NULL, + descrizione TEXT, + categoria VARCHAR(50), -- primo, secondo, contorno, dolce + prezzo DECIMAL(5,2), + disponibile BOOLEAN DEFAULT true, + ingredienti TEXT, -- Testo libero + allergeni JSONB, -- Array di allergeni: ["glutine", "lattosio", ...] + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE pasti ( + id SERIAL PRIMARY KEY, + data_pasto DATE NOT NULL, + tipo_pasto VARCHAR(20) NOT NULL, -- colazione, pranzo, cena + disponibile BOOLEAN DEFAULT true, + turno VARCHAR(20) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(data_pasto, tipo_pasto) +); + +CREATE TABLE prenotazioni ( + id SERIAL PRIMARY KEY, + user_id VARCHAR(100) NOT NULL, -- Estratto dal JWT + pasto_id INTEGER REFERENCES pasti(id) ON DELETE CASCADE, + pietanze_selezionate JSONB, -- Lista di pietanze + note TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(user_id, pasto_id) +); diff --git a/setup_db.py b/setup_db.py new file mode 100644 index 0000000..9671c8c --- /dev/null +++ b/setup_db.py @@ -0,0 +1,37 @@ +import psycopg2 + +def execute_sql_file(file_path, connection): + with open(file_path, 'r') as file: + sql = file.read() + with connection.cursor() as cursor: + cursor.execute(sql) + connection.commit() + +def main(): + # Configurazione del database + db_config = { + "dbname": "postgres", + "user": "postgres", + "password": "example", + "host": "localhost", + "port": 5432 + } + + try: + # Connessione al database + connection = psycopg2.connect(**db_config) + print("Connessione al database riuscita.") + + # Esecuzione dello script SQL + execute_sql_file('schema.sql', connection) + print("Script SQL eseguito con successo.") + + except Exception as e: + print(f"Errore durante la configurazione del database: {e}") + finally: + if connection: + connection.close() + print("Connessione al database chiusa.") + +if __name__ == "__main__": + main()