🗳️ Focolari Voting System
Sistema di controllo accessi per le assemblee di voto del Movimento dei Focolari.
📖 Descrizione
Applicazione web ottimizzata per tablet che gestisce i varchi d'ingresso alle sale votazione. Il sistema utilizza lettori RFID USB (che emulano tastiera) per identificare validatori e partecipanti.
🏗️ Struttura Progetto
VotoFocolari/
├── dev.sh # Script sviluppo (install, dev, server, build, ...)
├── ai-prompts/ # Documentazione sviluppo e prompt
├── backend-mock/ # API mock in Python FastAPI
│ └── static/ # Frontend buildato (generato)
└── frontend/ # App React + TypeScript + Tailwind
🚀 Quick Start
Setup Iniziale
./dev.sh install
Sviluppo (hot reload)
./dev.sh dev
# Backend API: http://localhost:8000
# Frontend Dev: http://localhost:5173
Produzione Locale
./dev.sh server
# App completa: http://localhost:8000/badge
Altri Comandi
./dev.sh build # Solo build frontend
./dev.sh backend # Solo backend (API)
./dev.sh frontend # Solo frontend dev
./dev.sh test # Esegue i test frontend
./dev.sh test:watch # Test in watch mode
./dev.sh test:dev # Server + test watch mode
./dev.sh shell # Shell pipenv backend
./dev.sh clean # Pulisce build e cache
./dev.sh help # Mostra tutti i comandi
🧪 Test
Il progetto include una suite completa di 56 test automatici per il frontend.
Comandi Test
# Esegue tutti i test una volta (CI/CD)
./dev.sh test
# Test in watch mode - riesegue automaticamente quando modifichi i file
./dev.sh test:watch
# Server + Test watch mode - utile per test manuali + automatici insieme
./dev.sh test:dev
Come usare test:watch
Il watch mode è utile durante lo sviluppo:
-
Avvia i test in watch mode:
./dev.sh test:watch -
Cosa succede:
- I test vengono eseguiti immediatamente
- Vitest rimane in ascolto dei cambiamenti
- Quando salvi un file
.tso.tsx, i test correlati vengono rieseguiti automaticamente
-
Comandi interattivi (mentre è in esecuzione):
a- Riesegui tutti i testf- Riesegui solo i test fallitip- Filtra per nome filet- Filtra per nome testq- Esci
-
Per test manuali + automatici insieme:
./dev.sh test:devQuesto avvia sia il server (http://localhost:8000/badge) che i test in watch mode, così puoi:
- Testare manualmente nel browser
- Vedere i test automatici aggiornarsi in tempo reale
Copertura Test (56 test)
| Categoria | Test | Descrizione |
|---|---|---|
| useRFIDScanner | 20 | Pattern US/IT, timeout, ESC, Enter handling |
| API Service | 13 | Endpoint, error handling, badge stringa, bypass protection |
| UserCard | 9 | Rendering, stati ammesso/non ammesso |
| Configurazione | 14 | Timeout, sessione, invalidazione server restart |
Test Critico: Backend Safety
Il test should block non-ammesso user even if frontend bug sends request verifica che:
- Anche se un bug nel frontend permette di inviare una richiesta per un utente NON ammesso
- Il backend risponde comunque con
success: false - Questo è un controllo di sicurezza a livello server
Tipi di Test
⚠️ Nota: I test attuali sono unit test che girano in un DOM simulato (jsdom). Non aprono un browser reale. Per test End-to-End (E2E) che aprono il browser, servirebbe Playwright o Cypress (non ancora implementato).
Con npm direttamente
cd frontend
npm run test:run # Esecuzione singola
npm run test # Watch mode
npm run test:coverage # Con coverage report
🎭 Test E2E (Playwright)
Test End-to-End che aprono un browser reale e verificano i flussi completi dell'applicazione.
Comandi E2E
| Comando | Descrizione |
|---|---|
./dev.sh test:e2e |
Test headless (senza vedere il browser), server avviato automaticamente |
./dev.sh test:e2e:headed |
Test con browser visibile, server avviato automaticamente |
./dev.sh test:e2e:ui |
Apre Playwright UI (IDE interattivo per debug), server avviato automaticamente |
# Test veloci (headless)
./dev.sh test:e2e
# Test con browser visibile (per vedere cosa succede)
./dev.sh test:e2e:headed
# Debug interattivo (clicca sui test nell'UI)
./dev.sh test:e2e:ui
# Filtrare test specifici
./dev.sh test:e2e:headed -- --grep "login"
./dev.sh test:e2e:headed -- --project=chromium
Test E2E Inclusi
| Categoria | Test |
|---|---|
| Flusso Validatore | Login, password, annulla |
| Flusso Partecipante | Badge ammesso/non ammesso/non trovato |
| Conferma Ingresso | Success modal, warning non ammesso |
| Sicurezza | Backend blocca non-ammesso → errore frontend |
| Debug & Session | Pagina debug, logout, persistenza sessione |
Test Critico: Sicurezza Backend
Il test E2E backend blocca non-ammesso → frontend mostra errore:
- Intercetta la chiamata API
/entry-request - Forza risposta
success: false(simula backend che blocca) - Verifica che il frontend NON mostri il carosello di benvenuto
- Verifica che mostri un messaggio di errore
Questo garantisce che anche se il frontend ha bug, il backend fa da ultimo baluardo.
📚 Documentazione
Per dettagli tecnici, consulta:
Guide:
PATH_STRUCTURE.md- Struttura path del sistema (/badgeper frontend,/api/*per API)CHANGE_BASE_PATH.md- Come cambiare il path base del frontend o delle APINETWORK_ACCESS.md- Come accedere al server da altri dispositivi (tablet)
Piani di sviluppo (ai-prompts/):
00-welcome-agent.md- Panoramica progetto01-backend-plan.md- Piano sviluppo backend02-frontend-plan.md- Piano sviluppo frontend
🔐 Credenziali Test
- Password Validatore:
focolari - Badge Test: Qualsiasi badge (es.
0008988288,0007399575)
I badge di test con anagrafica sono documentati in backend-mock/API_SPECIFICATION.md.
🔍 Debug
Accedi a /debug per diagnostica RFID in tempo reale.
🏭 Build e Deploy in Produzione
Compilazione Frontend
Il frontend React deve essere compilato in file statici prima del deploy.
# Build automatica (usa dev.sh)
./dev.sh build
# Oppure manualmente
cd frontend
npm install
npm run build
I file compilati vengono generati in frontend/dist/.
Struttura Build Output
frontend/dist/
├── index.html
├── favicon.jpg
└── assets/
├── index-XXXXX.js # Bundle JS minificato
├── index-XXXXX.css # CSS minificato
└── FocolareMovLogo-XXXXX.jpg
Deploy
Opzione 1: Backend Mock (test/demo)
Il backend mock Python serve automaticamente il frontend dalla cartella frontend/dist/:
./dev.sh server --host 0.0.0.0 --port 8000
L'applicazione completa sarà disponibile su http://<IP>:8000/.
Opzione 2: Backend Reale
Il backend di produzione deve:
- Implementare le API secondo le specifiche in
backend-mock/API_SPECIFICATION.md - Servire i file statici dalla cartella
frontend/dist/sulla root/ - Configurare CORS se frontend e backend sono su domini diversi
Esempio con un web server (nginx, Apache, etc.):
server {
listen 80;
server_name voting.focolari.org;
# Frontend statico
location / {
root /var/www/focolari/frontend/dist;
try_files $uri $uri/ /index.html;
}
# API proxy verso backend
location /info-room { proxy_pass http://localhost:8080; }
location /login-validate { proxy_pass http://localhost:8080; }
location /anagrafica/ { proxy_pass http://localhost:8080; }
location /entry-request { proxy_pass http://localhost:8080; }
}
Opzione 3: Tutto-in-uno (consigliata)
Il backend reale serve direttamente i file statici:
# Esempio FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
app.mount("/assets", StaticFiles(directory="frontend/dist/assets"))
@app.get("/")
async def serve_frontend():
return FileResponse("frontend/dist/index.html")
Variabili d'Ambiente
Il frontend non richiede variabili d'ambiente. Le API sono chiamate con path relativi (/info-room, etc.), quindi
funziona automaticamente indipendentemente dal dominio o porta.
Requisiti Sistema Produzione
- Python 3.11+ con
pipenv(per backend mock) - Node.js 18+ con
npm(solo per build frontend) - Browser moderno (Chrome, Safari, Firefox) sul tablet
- Lettore RFID configurato come tastiera HID
📄 Licenza
Progetto privato - Movimento dei Focolari