- Python 93.3%
- Shell 4.7%
- Dockerfile 2%
| data | ||
| docs/superpowers | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| app.py | ||
| CLAUDE.md | ||
| compose.yml | ||
| config.py | ||
| disponibilita.md | ||
| Dockerfile | ||
| export_report.py | ||
| local_start.sh | ||
| prompt.md | ||
| pyproject.toml | ||
| README.md | ||
| slot.md | ||
| slots.py | ||
| store.py | ||
| validate_slot_change.py | ||
Prenotazione sessioni di inserimento assistito
App Streamlit + SQLite per prenotare gli slot di inserimento assistito (11–12 giugno 2026).
Configurazione
Due file JSON in data/ (montati come volume /data nel container):
invitati.json— chi può prenotare. Email → nominativo:{ "mario.rossi@gcf.it": {"nome": "Mario", "cognome": "Rossi"} }slot.json— capienza per slot (= numero assistenti). La chiave definisce data/ora nel formatoYYYYMMDDHHH:MM, es.20260611H15:00. È questo file a stabilire quali slot esistono:{ "20260611H15:00": 3, "20260611H15:30": 2 }
Partire dagli esempi: cp data/invitati.example.json data/invitati.json e
cp data/slot.example.json data/slot.json.
Avvio in locale
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
EXPORT_TOKEN=<segreto> .venv/bin/streamlit run app.py
Variabili d'ambiente: INVITATI_PATH, SLOT_PATH, DB_PATH, EXPORT_TOKEN.
Report
Due modi per ottenere il report (chi ha prenotato cosa + posti liberi):
- URL nascosto — visitare
https://<host>/?export=<EXPORT_TOKEN>. Mostra la tabella prenotazioni con download CSV e il riepilogo per slot. Senza il token corretto la sezione non compare. - CLI —
python export_report.py --db <db> --slot <slot.json> --out report.csv(dentro il container:docker exec <container> python export_report.py ...).
Il file SQLite è comunque sul volume in DB_PATH.
Docker
Build e deploy seguono le procedure dell'infrastruttura GCF (skill gcf-docker-build
e gcf-docker-deploy). Il container espone la porta 8501 e usa il volume /data per
config, DB e CSV.
docker build -t sondaggio:dev .
docker run --rm -p 8501:8501 \
-e EXPORT_TOKEN=segreto123 \
-v "$PWD/data:/data" \
sondaggio:dev
Produzione
Online su https://sondaggio.gcf-cloud.it (TLS Let's Encrypt via edge nginx su fwrz →
backend marte:8006). Lo stack vive in /docker/sondaggio/ su marte (compose.yml +
.env con EXPORT_TOKEN, mode 0600). data/ è di proprietà uid 1000 per consentire al
container la scrittura di prenotazioni.sqlite.
Aggiornare a una nuova versione:
# build + push dalla workstation (marte non raggiunge la SSH del registry)
docker build --platform linux/amd64 \
-t git.gcf-cloud.it/gcf_rd/sondaggio:<ver> -t git.gcf-cloud.it/gcf_rd/sondaggio:latest .
docker push git.gcf-cloud.it/gcf_rd/sondaggio:<ver>
docker push git.gcf-cloud.it/gcf_rd/sondaggio:latest
# poi su marte (sudo): allinea l'image tag in compose.yml e
docker compose -f /docker/sondaggio/compose.yml up -d
Sostituire la lista invitati: rimpiazzare /docker/sondaggio/data/invitati.json e
riavviare lo stack. La griglia slot di produzione coincide con data/slot.example.json.
Nota nginx: il vhost richiede gli header WebSocket (
Upgrade/Connection,proxy_http_version 1.1) per/_stcore/stream, altrimenti la UI Streamlit resta su "Connecting". Il playbook genericosetup-nginx-reverseproxy.ymlnon li include e sovrascrive il vhost a ogni run: dopo averlo rieseguito, reiniettare gli header.
Aggiornare slot.json in produzione
Quando i formatori cambiano disponibilità, aggiornare slot.json richiede attenzione:
non si può ridurre o rimuovere uno slot che ha già prenotazioni senza prima gestire gli utenti coinvolti.
Lo script validate_slot_change.py (standalone, nessuna dipendenza da Streamlit) valida il cambio
prima di applicarlo.
Flusso di lavoro
-
Copia file da marte in locale:
scp marte:/docker/sondaggio/data/prenotazioni.sqlite ./data/ scp marte:/docker/sondaggio/data/slot.json ./data/ scp marte:/docker/sondaggio/data/invitati.json ./data/ -
Crea
data/slot.new.jsoncon le nuove disponibilità. -
Lancia la validazione:
python validate_slot_change.py \ --db data/prenotazioni.sqlite \ --slot data/slot.json \ --new-slot data/slot.new.json \ --invitati data/invitati.json \ --out report.csvExit code:
0— Nessun conflitto. Sicuro aggiornare.1— Ci sono conflitti. Non aggiornare finché non risolti.
-
Se OK (exit code 0):
scp data/slot.new.json marte:/docker/sondaggio/data/slot.json ssh marte "docker restart sondaggio" -
Se KO (exit code 1): apri
report.csv— per ogni slot conflitto trovi:- tipo (
rimosso/ridotto) - capienza vecchia / nuova
- prenotati / in eccesso
- email e nominativo degli utenti da contattare
Gestisci manualmente (annulla / sposta le prenotazioni in eccesso) e ripeti la validazione.
- tipo (
Test e qualità
.venv/bin/pytest # test
.venv/bin/ruff check . # lint
.venv/bin/mypy . # type check
Supporto
Fabio Angelone — helpdesk@gcf.it · Ludovica Roncella — hr@gcf.it / l.roncella@gcf.it