feat: setup iniziale sistema controllo accessi Focolari

Struttura progetto:
- Backend mock Python (FastAPI) con API per gestione varchi
- Frontend React + TypeScript + Vite + Tailwind CSS
- Documentazione e piani di sviluppo

Backend (backend-mock/):
- API REST: /info-room, /login-validate, /anagrafica, /entry-request
- Dati mock: 7 utenti, validatore (999999/focolari)
- CORS abilitato, docs OpenAPI automatiche
- Configurazione pipenv per ambiente virtuale

Frontend (frontend/):
- State machine completa per flusso accesso varco
- Hook useRFIDScanner per lettura badge (pattern singolo)
- Componenti UI: Logo, Button, Input, Modal, UserCard, Timer
- Schermate: Loading, Login, ActiveGate, Success/Error Modal
- Design system con colori Focolari
- Ottimizzato per tablet touch

Documentazione (ai-prompts/):
- Welcome guide per futuri agenti
- Piano sviluppo backend e frontend con checklist

DA COMPLETARE:
- Hook RFID multi-pattern (US/IT/altri layout tastiera)
- Pagina /debug per diagnostica in loco
- Logging console strutturato
This commit is contained in:
2026-01-17 18:20:55 +01:00
commit 21b509c6ba
40 changed files with 7453 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
# 🎯 Focolari Voting System - Guida Agente
## Panoramica Progetto
**Nome:** Sistema Controllo Accessi "Focolari Voting System"
**Committente:** Movimento dei Focolari
**Scopo:** Gestione dei varchi di accesso per le assemblee di voto del Movimento.
### Contesto d'Uso
Il sistema funziona su **tablet Android** (via browser Chrome) posizionati ai varchi d'ingresso delle sale votazione. Ogni tablet è collegato a un **lettore RFID USB** che emula tastiera.
---
## 🏗️ Architettura
```
VotoFocolari/
├── ai-prompts/ # Documentazione e piani di sviluppo
├── backend-mock/ # Python FastAPI (server mock)
│ ├── main.py # Entry point con argparse
│ ├── Pipfile # Dipendenze pipenv
│ ├── api/ # Routes FastAPI
│ ├── schemas/ # Modelli Pydantic
│ └── data/ # Dataset JSON (default, test)
└── frontend/ # React + TypeScript + Vite + Tailwind
└── src/
├── App.tsx # State machine principale
├── hooks/ # Custom hooks (RFID scanner)
├── components/ # UI components
├── screens/ # Schermate complete
├── services/ # API layer
├── types/ # TypeScript definitions
└── tests/ # Test automatici use case
```
---
## 🔧 Stack Tecnologico
### Backend Mock
- **Python 3.10+**
- **FastAPI** - Framework web asincrono
- **Uvicorn** - ASGI server
- **Pydantic** - Validazione dati
- **pipenv** - Gestione ambiente virtuale
- **argparse** - Parametri CLI (porta, dataset)
### Frontend
- **React 19** - UI Library
- **TypeScript 5.9** - Type safety
- **Vite 7** - Build tool
- **Tailwind CSS 4** - Styling utility-first
- **React Router** - Routing (/, /debug)
- **Vitest** - Testing framework
- **Design:** Ottimizzato per touch tablet
---
## 🎨 Design System
| Colore | Hex | Uso |
|--------|-----|-----|
| Blu Istituzionale | `#0072CE` | Colore primario, brand |
| Arancio Accento | `#F5A623` | Azioni secondarie |
| Giallo | `#FFD700` | Evidenze |
| Verde Success | `#22C55E` | Conferme, ammesso |
| Rosso Error | `#EF4444` | Errori, non ammesso |
---
## 📟 Logica RFID (CRITICA)
Il lettore RFID simula una tastiera. **Non possiamo distinguerlo dalla digitazione umana** in base alla velocità.
### Protocollo
- **Formato:** `<start_sentinel><codice><end_sentinel>`
- **Esempio US:** `;00012345?`
- **Esempio IT:** `ò00012345_`
### Pattern Supportati
```typescript
const VALID_PATTERNS = [
{ start: ';', end: '?' }, // Layout US
{ start: 'ò', end: '_' }, // Layout IT
];
```
### Strategia
1. Ascolto globale `keydown`
2. Se ricevo un carattere `start` → avvio buffer + timeout (2.5s)
3. Accumulo caratteri nel buffer
4. Se ricevo il corretto `end` → emetto codice pulito
5. Se timeout scade → scarto buffer
---
## 🔄 State Machine Applicativa
```
LOADING → WAITING_VALIDATOR → [badge validatore]
→ VALIDATOR_PASSWORD → [password OK]
→ GATE_ACTIVE → [badge partecipante]
→ SHOWING_USER → [badge validatore]
→ SUCCESS_MODAL (5s, carosello multilingua) → GATE_ACTIVE
```
---
## 🌍 Messaggi Benvenuto (Frontend)
Il backend risponde in modo **asettico** (solo `success: true`).
Il frontend mostra un **carosello automatico** di messaggi multilingua:
- Italiano, English, Français, Deutsch, Español, Português, 中文, 日本語
Scorrimento ogni ~2 secondi, durata modale 5 secondi.
---
## 📁 File Chiave
| File | Descrizione |
|------|-------------|
| `backend-mock/main.py` | Entry point con argparse |
| `backend-mock/api/routes.py` | Definizione endpoint |
| `backend-mock/schemas/models.py` | Modelli Pydantic |
| `backend-mock/data/*.json` | Dataset utenti |
| `frontend/src/hooks/useRFIDScanner.ts` | Cuore del sistema - gestione lettore |
| `frontend/src/App.tsx` | State machine e orchestrazione |
| `frontend/src/components/WelcomeCarousel.tsx` | Carosello multilingua |
| `frontend/src/screens/DebugScreen.tsx` | Diagnostica RFID |
| `frontend/src/tests/` | Test automatici use case |
---
## 🚀 Quick Start
### Backend
```bash
cd backend-mock
pipenv install
pipenv run python main.py # Default
pipenv run python main.py -p 9000 # Porta custom
pipenv run python main.py -d data/test.json # Dataset test
```
### Frontend
```bash
cd frontend
npm install
npm run dev # Sviluppo
npm run test # Test suite
npm run test:ui # Test con UI
```
---
## 🧪 Test Automatici
Suite di test per validazione use case:
| Test | Descrizione |
|------|-------------|
| UC01 | Login validatore |
| UC02 | Accesso partecipante ammesso |
| UC03 | Accesso negato |
| UC04 | Timeout sessione |
| UC05 | Cambio rapido badge |
| UC06 | Pattern RFID multipli |
---
## 🔍 Debug
### Console Browser
Tutti i log sono prefissati:
- `[RFID]` - Eventi lettore badge
- `[FLOW]` - Transizioni stato
- `[API]` - Chiamate HTTP
### Pagina Debug (`/debug`)
Accesso: logo cliccabile 5 volte.
Mostra in tempo reale:
- Ultimi 20 tasti premuti
- Stato scanner (idle/scanning)
- Buffer corrente
- Pattern attivo
---
## ⚠️ Note Importanti
1. **Badge Validatore:** `999999` con password `focolari`
2. **Sessione:** 30 minuti di timeout, salvata in localStorage
3. **Timeout utente:** 60 secondi sulla schermata decisione
4. **Multi-layout:** Il sistema supporta RFID su tastiera US e IT
5. **Backend asettico:** Nessun messaggio multilingua dal server
6. **Git:** Il progetto sfrutta un Repository per versionare e sviluppare, ma solo l'utente può eseguire comandi git, eccetto se richiesto diversamente, l'agente può solo chiedere di eseguire o suggerire cosa fare, ma mai prendere iniziative
---
## 📚 Documentazione Correlata
- `01-backend-plan.md` - Piano sviluppo backend
- `02-frontend-plan.md` - Piano sviluppo frontend

View File

@@ -0,0 +1,181 @@
# 📋 Piano Sviluppo Backend Mock
## Obiettivo
Server FastAPI mock per simulare il backend del sistema di controllo accessi.
Struttura modulare con separazione tra API, modelli e dati.
---
## Struttura Target
```
backend-mock/
├── main.py # Entry point con argparse
├── Pipfile # Dipendenze pipenv
├── requirements.txt # Backup dipendenze
├── .gitignore
├── api/
│ ├── __init__.py
│ └── routes.py # Definizione endpoint
├── schemas/
│ ├── __init__.py
│ └── models.py # Modelli Pydantic
└── data/
├── users_default.json # Dataset utenti default
└── users_test.json # Dataset per test
```
---
## Checklist Sviluppo
### 1. Setup Progetto
- [x] Creare cartella `backend-mock/`
- [x] Creare `Pipfile` per pipenv
- [x] Configurare `.gitignore` per Python
- [ ] Creare struttura cartelle (`api/`, `schemas/`, `data/`)
### 2. Modelli Pydantic (`schemas/models.py`)
- [x] `LoginRequest` - badge + password
- [x] `EntryRequest` - user_badge + validator_password
- [x] `UserResponse` - dati utente + warning opzionale
- [x] `RoomInfoResponse` - nome sala + meeting_id
- [x] `LoginResponse` - success + message + token
- [x] `EntryResponse` - success + message (SENZA welcome_message)
- [ ] **DA FARE:** Spostare modelli in file dedicato
### 3. Dati Mock (`data/*.json`)
- [x] Costanti validatore (badge `999999`, password `focolari`)
- [x] Lista utenti mock (7 utenti con dati realistici)
- [x] Mix di ruoli: Votante, Tecnico, Ospite
- [x] Alcuni con `ammesso: false` per test
- [x] URL foto placeholder (randomuser.me)
- [ ] **DA FARE:** Estrarre dati in file JSON separato
- [ ] **DA FARE:** Creare dataset alternativo per test
- [ ] **DA FARE:** Caricare dati dinamicamente all'avvio
**Nota:** I messaggi di benvenuto multilingua sono stati **RIMOSSI** dal backend.
Il frontend gestirà autonomamente la visualizzazione internazionale con carosello.
### 4. Routes API (`api/routes.py`)
- [x] `GET /info-room` - info sala
- [x] `POST /login-validate` - autenticazione validatore
- [x] `GET /anagrafica/{badge_code}` - ricerca utente
- [x] Pulizia caratteri sentinel dal badge
- [x] Confronto con e senza zeri iniziali
- [x] Warning automatico se non ammesso
- [x] `POST /entry-request` - registrazione ingresso
- [x] Verifica password validatore
- [x] Verifica utente ammesso
- [x] Risposta asettica (solo success + message)
- [ ] **DA FARE:** Spostare routes in file dedicato
### 5. Entry Point (`main.py`)
- [x] Blocco `if __name__ == "__main__"`
- [x] Configurazione uvicorn (host, port)
- [x] Messaggi console all'avvio
- [ ] **DA FARE:** Implementare argparse con opzioni:
- `--port` / `-p` : porta server (default: 8000)
- `--data` / `-d` : path file JSON dati (default: `data/users_default.json`)
- `--host` : host binding (default: `0.0.0.0`)
- [ ] **DA FARE:** Caricamento dinamico dati da JSON
- [ ] **DA FARE:** Import routes da modulo `api`
### 6. Struttura Base FastAPI
- [x] Import FastAPI e dipendenze
- [x] Configurazione app con titolo e descrizione
- [x] Middleware CORS (allow all origins)
- [x] Endpoint root `/` per health check
- [ ] **DA FARE:** Refactor in struttura modulare
---
## Schema File JSON Dati
```json
{
"validator": {
"badge": "999999",
"password": "focolari"
},
"room": {
"room_name": "Sala Assemblea",
"meeting_id": "VOT-2024"
},
"users": [
{
"badge_code": "000001",
"nome": "Maria",
"cognome": "Rossi",
"url_foto": "https://...",
"ruolo": "Votante",
"ammesso": true
}
]
}
```
---
## Comandi Esecuzione
### Avvio Standard
```bash
cd backend-mock
pipenv install
pipenv run python main.py
```
### Avvio con Parametri Custom
```bash
# Porta diversa
pipenv run python main.py --port 9000
# Dataset test
pipenv run python main.py --data data/users_test.json
# Combinato
pipenv run python main.py -p 9000 -d data/users_test.json
```
---
## Test Rapidi
```bash
# Health check
curl http://localhost:8000/
# Info sala
curl http://localhost:8000/info-room
# Ricerca utente
curl http://localhost:8000/anagrafica/000001
# Login validatore
curl -X POST http://localhost:8000/login-validate \
-H "Content-Type: application/json" \
-d '{"badge": "999999", "password": "focolari"}'
# Richiesta ingresso (risposta asettica)
curl -X POST http://localhost:8000/entry-request \
-H "Content-Type: application/json" \
-d '{"user_badge": "000001", "validator_password": "focolari"}'
```
---
## Note Implementative
- Gli endpoint puliscono automaticamente i caratteri `;`, `?`, `ò`, `_` dai badge
- Il confronto badge avviene sia con che senza zeri iniziali
- Le risposte seguono lo standard HTTP (200 OK, 401 Unauthorized, 404 Not Found, 403 Forbidden)
- La documentazione OpenAPI è auto-generata su `/docs`
- **Risposta `/entry-request`:** JSON asettico `{ success: true, message: "..." }` senza messaggi multilingua

View File

@@ -0,0 +1,305 @@
# 📋 Piano Sviluppo Frontend
## Obiettivo
Applicazione React per tablet che gestisce il flusso di accesso ai varchi votazione, con lettura badge RFID.
Include sistema di test automatici per validazione e regression detection.
---
## Checklist Sviluppo
### 1. Setup Progetto
- [x] Inizializzare Vite + React + TypeScript
- [x] Installare Tailwind CSS 4
- [x] Configurare `tsconfig.json`
- [x] Configurare `vite.config.ts`
- [x] Configurare `.gitignore`
### 2. Design System
- [x] Configurare colori custom in Tailwind
- [x] `focolare-blue: #0072CE`
- [x] `focolare-orange: #F5A623`
- [x] `focolare-yellow: #FFD700`
- [x] Stili globali in `index.css`
- [x] Animazioni custom (fade-in, slide-up, pulse-error, blink)
- [x] Classe `.glass` per effetto glassmorphism
### 3. Tipi TypeScript (`types/index.ts`)
- [x] `RoomInfo` - info sala
- [x] `User` - dati utente
- [x] `LoginRequest/Response`
- [x] `EntryRequest/Response` (SENZA welcome_message)
- [x] `AppState` - stati applicazione
- [x] `ValidatorSession` - sessione validatore
- [x] `RFIDScannerState` - stato scanner
- [x] `RFIDScanResult` - risultato scan
- [ ] **DA FARE:** Aggiornare `EntryResponse` rimuovendo `welcome_message`
### 4. API Service (`services/api.ts`)
- [x] Classe `ApiError` custom
- [x] Funzione `apiFetch` generica con error handling
- [x] `getRoomInfo()` - GET /info-room
- [x] `loginValidator()` - POST /login-validate
- [x] `getUserByBadge()` - GET /anagrafica/{badge}
- [x] `requestEntry()` - POST /entry-request
- [ ] **DA FARE:** Logging con prefisso `[API]`
### 5. Hook RFID Scanner (`hooks/useRFIDScanner.ts`)
#### Implementazione Base (v1)
- [x] Listener `keydown` globale
- [x] Stati: idle → scanning → idle
- [x] Singolo pattern (`;` / `?`)
- [x] Timeout sicurezza (3s)
- [x] `preventDefault` durante scan
- [x] Callback `onScan`, `onTimeout`, `onScanStart`
#### ⚠️ AGGIORNAMENTO RICHIESTO (v2) - Multi-Pattern
- [ ] Supporto pattern multipli (US, IT, altri)
```typescript
const VALID_PATTERNS = [
{ start: ';', end: '?' }, // Layout US
{ start: 'ò', end: '_' }, // Layout IT
];
```
- [ ] Rilevamento automatico pattern in uso
- [ ] Memorizzazione pattern attivo durante scan
- [ ] Validazione `end` solo per pattern corretto
- [ ] Logging avanzato con prefisso `[RFID]`
- [ ] Esportare info pattern attivo per debug page
### 6. Componenti UI (`components/`)
- [x] `Logo.tsx` - logo Focolari
- [x] `Button.tsx` - varianti primary/secondary/danger
- [x] `Input.tsx` - campo input styled
- [x] `Modal.tsx` - modale base
- [x] `RFIDStatus.tsx` - indicatore stato scanner
- [x] `UserCard.tsx` - card utente con foto e ruolo
- [x] `CountdownTimer.tsx` - timer con progress bar
- [x] `index.ts` - barrel export
- [ ] **DA FARE:** `WelcomeCarousel.tsx` - carosello messaggi multilingua
### 7. Schermate (`screens/`)
- [x] `LoadingScreen.tsx` - caricamento iniziale
- [x] `ValidatorLoginScreen.tsx` - attesa badge + password
- [x] `ActiveGateScreen.tsx` - varco attivo + scheda utente
- [x] `SuccessModal.tsx` - conferma ingresso fullscreen
- [x] `ErrorModal.tsx` - errore fullscreen
- [x] `index.ts` - barrel export
- [ ] **DA FARE:** `DebugScreen.tsx` - pagina diagnostica RFID
### 8. State Machine (`App.tsx`)
- [x] Stati applicazione gestiti
- [x] Integrazione `useRFIDScanner`
- [x] Gestione sessione validatore (localStorage)
- [x] Timeout sessione 30 minuti
- [x] Timeout utente 60 secondi
- [x] Cambio rapido badge partecipante
- [x] Conferma con badge validatore
- [ ] **DA FARE:** Logging transizioni con prefisso `[FLOW]`
### 9. Modale Successo - Carosello Internazionale
#### ⚠️ MODIFICA RICHIESTA
Il backend **NON** restituisce più messaggi multilingua.
Il frontend gestisce autonomamente la visualizzazione con un **carosello automatico**.
**Specifiche:**
- [ ] Creare componente `WelcomeCarousel.tsx`
- [ ] Lista messaggi di benvenuto in diverse lingue:
```typescript
const WELCOME_MESSAGES = [
{ lang: 'it', text: 'Benvenuto!' },
{ lang: 'en', text: 'Welcome!' },
{ lang: 'fr', text: 'Bienvenue!' },
{ lang: 'de', text: 'Willkommen!' },
{ lang: 'es', text: 'Bienvenido!' },
{ lang: 'pt', text: 'Bem-vindo!' },
{ lang: 'zh', text: '欢迎!' },
{ lang: 'ja', text: 'ようこそ!' },
];
```
- [ ] Scorrimento automatico (es. ogni 2 secondi)
- [ ] Animazione transizione fluida (fade o slide)
- [ ] Modale fullscreen verde con carosello al centro
- [ ] Durata totale modale: 5 secondi
### 10. Debug & Diagnostica
#### ⚠️ DA IMPLEMENTARE
- [ ] Pagina `/debug` dedicata
- [ ] Log ultimi 20 tasti premuti (key + code)
- [ ] Stato scanner real-time (idle/scanning)
- [ ] Buffer corrente
- [ ] Pattern attivo (US/IT/...)
- [ ] Ultimo codice rilevato
- [ ] Timestamp eventi
- [ ] Link/pulsante nascosto per accesso debug (es. logo cliccabile 5 volte)
- [ ] Logging console strutturato:
- [ ] `[RFID]` - eventi scanner
- [ ] `[FLOW]` - transizioni stato
- [ ] `[API]` - chiamate HTTP
### 11. Routing
- [ ] Installare React Router
- [ ] Route principale `/`
- [ ] Route debug `/debug`
### 12. Test Automatici (E2E / Use Case Validation)
#### ⚠️ NUOVA SEZIONE
Sistema di test per validazione formale dei flussi e regression detection.
**Struttura:**
```
frontend/
├── src/
│ └── tests/
│ ├── usecase/
│ │ ├── UC01_ValidatorLogin.test.ts
│ │ ├── UC02_ParticipantAccess.test.ts
│ │ ├── UC03_DeniedAccess.test.ts
│ │ ├── UC04_SessionTimeout.test.ts
│ │ ├── UC05_QuickBadgeSwitch.test.ts
│ │ └── UC06_RFIDMultiPattern.test.ts
│ └── helpers/
│ ├── mockRFID.ts # Simulatore eventi tastiera RFID
│ └── testUtils.ts # Utility comuni
```
**Use Case da Testare:**
- [ ] **UC01 - Login Validatore**
- Simula badge validatore (`;999999?`)
- Inserisce password corretta
- Verifica transizione a stato `gate-active`
- Verifica sessione salvata in localStorage
- [ ] **UC02 - Accesso Partecipante Ammesso**
- Da stato `gate-active`
- Simula badge partecipante ammesso
- Verifica caricamento dati utente
- Simula badge validatore per conferma
- Verifica modale successo con carosello
- Verifica ritorno a `gate-active`
- [ ] **UC03 - Accesso Negato**
- Simula badge partecipante NON ammesso
- Verifica visualizzazione warning rosso
- Verifica che conferma validatore sia bloccata
- Verifica pulsante annulla funzionante
- [ ] **UC04 - Timeout Sessione**
- Verifica scadenza sessione 30 minuti
- Verifica redirect a login validatore
- Verifica pulizia localStorage
- [ ] **UC05 - Cambio Rapido Badge**
- Con utente a schermo
- Simula nuovo badge partecipante
- Verifica sostituzione immediata dati
- [ ] **UC06 - Pattern RFID Multipli**
- Testa pattern US (`;` / `?`)
- Testa pattern IT (`ò` / `_`)
- Verifica stesso risultato finale
**Dipendenze Test:**
```bash
npm install -D vitest @testing-library/react @testing-library/user-event jsdom
```
**Script npm:**
```json
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
}
}
```
---
## Correzioni Necessarie
### Hook RFID - Da Aggiornare
Il file `useRFIDScanner.ts` attualmente supporta **solo** il pattern US (`;` / `?`).
**Modifiche richieste:**
1. Aggiungere costante `VALID_PATTERNS` con pattern multipli
2. Modificare logica `handleKeyDown` per:
- Riconoscere qualsiasi `start` sentinel
- Memorizzare quale pattern è in uso
- Validare solo con l'`end` corrispondente
3. Aggiungere stato `activePattern` per debug
4. Migliorare logging
### Success Modal - Da Aggiornare
Attualmente usa `welcome_message` dal backend.
**Modifiche richieste:**
1. Rimuovere dipendenza da `welcome_message` API
2. Implementare `WelcomeCarousel` con messaggi hardcoded
3. Carosello auto-scroll ogni 2 secondi
4. Animazioni fluide tra messaggi
### Logging Console
Attualmente i log usano messaggi generici. Aggiornare tutti i `console.log` con prefissi standardizzati.
---
## Dipendenze da Aggiungere
```bash
# Routing
npm install react-router-dom
# Testing
npm install -D vitest @testing-library/react @testing-library/user-event jsdom @vitest/ui @vitest/coverage-v8
```
---
## Comandi Esecuzione
```bash
cd frontend
npm install
npm run dev # Sviluppo
npm run build # Build produzione
npm run test # Test suite
npm run test:ui # Test con UI interattiva
npm run test:coverage # Coverage report
```
---
## Note UI/UX
- Font grandi per leggibilità tablet
- Pulsanti touch-friendly (min 48px)
- Feedback visivo immediato su azioni
- Animazioni fluide ma non invasive
- Supporto landscape e portrait
- Carosello benvenuto: transizioni smooth, leggibilità massima