✂️ Documentazione Tecnica

Come funziona
PrenoTaglio

Sistema di prenotazione multi-salone con gestione intelligente della capacità per giorno, slot temporali e sovrapposizioni concorrenti.

Multi-tenant Anti-overbooking Collaboratori per giorno Slot dinamici Pausa pranzo Transazioni SQL

I 4 concetti chiave

Prima di capire come vengono gestite le sovrapposizioni, è essenziale comprendere i quattro pilastri del sistema.

⏱️
durata_slot
Durata del singolo slot
È la "granularità" della griglia oraria per ogni giorno. Determina ogni quanto vengono creati gli slot prenotabili. Si imposta per ogni giorno della settimana.
Venerdì: durata_slot = 10 min
→ Slot: 09:00, 09:10, 09:20, …
🔢
n_slot
Numero di slot del servizio
Quanti slot consecutivi occupa un servizio. Determina esclusivamente la durata del servizio. Non indica quanti collaboratori servono (sempre 1).
Taglio DONNA: n_slot = 6
Su Venerdì (10 min): dura 60 min
Su Mercoledì (20 min): dura 120 min
👥
n_collaboratori
Capacità parallela del giorno
Quante prenotazioni possono sovrapporsi nello stesso momento in quel giorno. È la "larghezza" della giornata — quante sedie/postazioni sono attive.
Venerdì: n_collaboratori = 6
→ Max 6 clienti contemporanei
Sabato: n_collaboratori = 1
→ 1 cliente alla volta
📐
Durata reale
n_slot × durata_slot
La durata effettiva del servizio cambia in base al giorno della settimana, poiché ogni giorno può avere una durata_slot diversa. Questo permette flessibilità massima.
Combo (n_slot=2):
• Venerdì (10min) → 20 min
• Mercoledì (20min) → 40 min
• Giovedì (30min) → 60 min
⚖️ Regola di disponibilità dello slot
Prenotazioni sovrapposte < n_collaboratori = ✅ DISPONIBILE
Se le prenotazioni attive che si sovrappongono all'orario richiesto raggiungono n_collaboratori, lo slot è pieno.
Ogni prenotazione occupa sempre esattamente 1 posto, indipendentemente dal servizio.

6 esempi di gestione sovrapposizioni

Scenari reali ordinati per complessità crescente, con visualizzazione temporale e analisi slot per slot.

1
Scenario base
Sabato con 1 collaboratore — il giorno più stretto
Cosa succede quando n_collaboratori = 1 e arrivano richieste diverse
📅 Sabato ⏱ slot: 10 min 👥 collaboratori: 1 🕘 09:00 → 18:00
09:0009:10 09:2009:30 09:4010:00
Collaboratore 1
✂️ UOMO
❌ DONNA (richiesta)
Non disponibile alle 09:00 (pieno)
✅ DONNA (09:10)
✂️ DONNA (6 slot = 60 min)
DONNA alle 09:00
1 prenotazione (UOMO) già presente. 1 ≥ 1 → slot pieno.
DONNA alle 09:10
UOMO finito alle 09:10. Sovrapposizioni: 0 < 1 → accettata.
⚠️
UOMO alle 09:10
Se la DONNA è già confermata, 1 ≥ 1 → rifiutato.
Regola: Con 1 solo collaboratore, il salone funziona come una fila singola. Il servizio più lungo blocca tutto il suo periodo — chi arriva dopo deve aspettare la fine.
2
Scenario intermedio
Venerdì pieno — 5 DONNA + 1 UOMO alle 09:00
Lo scenario descritto dall'utente: cosa si può prenotare alle 09:10?
📅 Venerdì ⏱ slot: 10 min 👥 collaboratori: 6 🕘 09:00 → 18:00
09:0009:10 09:2009:40 10:0010:10
Collab. 1
DONNA 60min
Collab. 2
DONNA 60min
Collab. 3
DONNA 60min
Collab. 4
DONNA 60min
Collab. 5
DONNA 60min
Collab. 6
UOMO 10m
❌ nuova DONNA
❌ 09:00
✅ da 09:10 (60min)
OrarioSovrapposizioni attivePosti liberiNuova DONNA?Nuovo UOMO?
09:006 (5 DONNA + 1 UOMO)0❌ NO❌ NO
09:105 (5 DONNA)1✅ 1 sola✅ 1 solo
10:0006✅ fino a 6✅ fino a 6
Attenzione: a 09:10 si può prenotare una sola persona (DONNA o UOMO, non entrambi), perché le 5 DONNA occupano 5/6 posti fino alle 10:00.
3
Scenario avanzato
La stratificazione progressiva — servizi a durate miste
Prenotazioni che iniziano in momenti diversi creano un "muro mobile" di disponibilità
📅 Venerdì ⏱ slot: 10 min 👥 collaboratori: 6
09:0009:10 09:2009:30 09:4010:00 10:1010:20
D1 (09:00)
DONNA
D2 (09:10)
DONNA
D3 (09:10)
DONNA
D4 (09:20)
DONNA
U1 (09:30)
UOMO
B1 (09:40)
BIMBO
OrarioPrenotazioni sovrapposteLiberi/6Nuova DONNA?
09:00D1 = 15✅ fino a 5
09:10D1 + D2 + D3 = 33✅ fino a 3
09:20D1 + D2 + D3 + D4 = 42✅ fino a 2
09:30D1 + D2 + D3 + D4 + U1 = 51✅ 1 sola
09:40D2 + D3 + D4 + B1 = 42✅ fino a 2
10:00D2 + D3 + D4 = 33✅ fino a 3
10:10D4 = 15✅ fino a 5
10:2006✅ fino a 6
Chiave: la disponibilità non è fissa per tutta la mattina — si calcola slot per slot considerando tutte le prenotazioni che si sovrappongono in quel preciso momento.
4
Scenario avanzato
La pausa pranzo — martedì con buco 12:00–13:30
Come si comportano i servizi lunghi a ridosso della pausa? Il sistema li taglia automaticamente
📅 Martedì ⏱ slot: 20 min 👥 collaboratori: 5 ☕ pausa: 12:00–13:30 🕘 08:00–18:00
11:00 11:20 11:40 12:00 PAUSA 13:30 13:50
🚫 Pausa
12:00 → 13:30
✅ DONNA 11:00
DONNA (60 min) → finisce a 12:00 ✅
❌ DONNA 11:20
Finirebbe a 12:20 → entra in pausa → slot NON generato
✅ DONNA 13:30
DONNA (60min) → 14:30 ✅
DONNA alle 11:00
11:00 + 60min = 12:00. Finisce esattamente all'inizio pausa. Slot valido.
DONNA dalle 11:20
11:20 + 60min = 12:20. Sforerebbe nella pausa. Lo slot non viene proprio generato.
DONNA alle 13:30
Primo slot valido dopo la pausa. 13:30 + 60min = 14:30 → OK.
Il sistema genera due blocchi separati di slot: 08:00–12:00 e 13:30–18:00. I servizi che finirebbero durante la pausa vengono automaticamente esclusi dalla griglia prenotabile.
5
Scenario critico
Anti-overbooking — due utenti prenotano lo stesso slot in contemporanea
Il meccanismo SELECT FOR UPDATE che previene le doppie prenotazioni
📅 Giovedì ⏱ slot: 30 min 👥 collaboratori: 1 🔒 SELECT FOR UPDATE

Ultimo slot disponibile: 09:00. Due utenti aprono la pagina, vedono lo slot verde, cliccano "Conferma" quasi contemporaneamente.

👤
Utente A — Maria
Conferma alle 10:03:01.240
✅ PRENOTAZIONE CONFERMATA
VS
👤
Utente B — Luca
Conferma alle 10:03:01.380
❌ SLOT NON PIÙ DISPONIBILE
⚙️ Come funziona il blocco SQL:

BEGIN TRANSACTION;
SELECT id FROM prenotazioni WHERE ... FOR UPDATE;  ← blocca le righe
-- Utente A: 0 conflitti → INSERT ✅ → COMMIT
-- Utente B: arriva dopo, trova 1 conflitto ≥ 1 → ROLLBACK ❌
  • 1
    Entrambi vedono lo slot verde
    La pagina di disponibilità mostra 0 prenotazioni su 1 possibile. Slot verde per entrambi.
  • 2
    Maria arriva prima — acquisisce il lock
    La transazione di Maria esegue SELECT FOR UPDATE. Le righe della tabella sono bloccate in scrittura. Luca deve aspettare.
  • 3
    Maria: 0 conflitti → INSERT → COMMIT
    Conta 0 prenotazioni sovrapposte. Inserisce la sua e fa COMMIT. Il lock viene rilasciato.
  • 4
    Luca: 1 conflitto ≥ 1 → ROLLBACK → Modale
    Ora conta 1 prenotazione (quella di Maria). 1 ≥ 1 → rollback. Il client riceve HTTP 409 e mostra il modale "Slot non più disponibile".
6
Scenario multi-giorno
Stesso servizio, giorni diversi — durate radicalmente diverse
Come n_slot × durata_slot cambia tutto in base al giorno della settimana

Il Combo (n_slot = 2) ha durate molto diverse nei vari giorni. Questo influenza quante prenotazioni si sovrappongono e quindi la capacità effettiva.

Giorno durata_slot n_collaboratori Durata Combo Prenotazioni/ora Slot 09:00 pieno dopo…
Martedì 20 min 5 40 min ~1,5/ora per collaboratore 5 Combo contemporanei alle 09:00 → pieno
Mercoledì 20 min 5 40 min ~1,5/ora per collaboratore 5 Combo contemporanei → pieno
Giovedì 30 min 1 60 min 1/ora 1 solo Combo alle 09:00 → pieno fino alle 10:00
Venerdì 10 min 6 20 min 3/ora per collaboratore 6 Combo contemporanei → pieno
Sabato 10 min 1 20 min 3/ora 1 solo Combo → pieno per 20 minuti
09:00 09:20 09:40 10:00 10:20 10:40
Gio (30min×2)
Combo 60min — pieno fino alle 10:00
Sab (10min×2)
20m
20m
20m
Ven (10min×2)
+6
+6
+6
📊
Throughput Giovedì
1 collaboratore × 60min = 1 Combo/ora. Il giorno meno produttivo.
🚀
Throughput Venerdì
6 collaboratori × 3 Combo/ora = 18 Combo/ora. Il giorno più produttivo.
⚖️
Flessibilità
Cambiare durata_slot o n_collaboratori dall'admin ha effetto immediato su tutti gli slot futuri.

Tabella di riferimento rapido

Situazione Condizione Risultato
Slot completamente libero0 sovrapposizioni < n_collaboratori✅ Disponibile
Slot parzialmente occupatoX sovrapposizioni < n_collaboratori✅ Disponibile
Slot al limiteX sovrapposizioni = n_collaboratori❌ Pieno
Giorno chiusoaperto = 0❌ Chiuso
Servizio cade in pausa pranzoora_fine > pausa_inizio❌ Slot non generato
Data passatadata < oggi❌ Non prenotabile
Chiusura straordinariadata IN chiusure❌ Chiuso
Doppia prenotazione concorrenteSELECT FOR UPDATE + count ≥ n_collab.⚠️ Secondo utente rifiutato