Piattaforma di voto real-time per elezione MVP con visualizzazione su LED Wall e votazione via mobile PWA.
- LED Wall Display: Visualizzazione real-time dei risultati con grafici animati
- PWA Mobile: App di voto ottimizzata per smartphone con device fingerprinting
- Real-time Updates: Aggiornamenti istantanei tramite WebSocket
- Anti-frode: Sistema di prevenzione voti multipli per dispositivo
- Admin Dashboard: Gestione completa sessioni di voto
- Temi Personalizzabili: Colori e stili configurabili per ogni sessione
- Frontend: React (LED Wall), Next.js (PWA)
- Backend: Node.js, Express, Socket.io
- Database: Firebase Firestore / MariaDB
- Real-time: Socket.io
- Styling: TailwindCSS
- Charts: Recharts
- Auth: JWT
- Node.js 18+
- npm o yarn
- Account Firebase (per Firestore) o MariaDB
- (Opzionale) Docker e Docker Compose
```bash git clone https://github.com/tuousername/voting-platform.git cd voting-platform ```
Backend: ```bash cd backend cp .env.example .env
```
```bash
cd backend npm install
cd ../frontend-ledwall npm install
cd ../frontend-pwa npm install ```
- Crea progetto Firebase
- Genera service account key
- Copia credenziali in .env
- Installa MariaDB
- Crea database: `CREATE DATABASE voting_platform;`
- Esegui migrations (se usi Prisma)
```bash cd backend npm run seed ```
```bash
cd backend npm run dev
cd frontend-ledwall npm start
cd frontend-pwa npm run dev ```
```bash docker-compose up -d ```
- Accedi a http://localhost:3001/admin
- Login con credenziali admin
- Crea nuova sessione di voto
- Avvia sessione quando pronto
- Apri http://localhost:3000?session=ID_SESSIONE
- Proietta su schermo grande
- I risultati si aggiornano in real-time
- Scansiona QR code dal LED Wall
- O vai a http://localhost:3002/vote/ID_SESSIONE
- Seleziona opzione e vota
- Un solo voto per dispositivo
```bash
cd backend npm test
cd frontend-ledwall npm test ```
```bash
cd frontend-ledwall vercel
cd frontend-pwa vercel ```
```bash
npm run build scp -r ./backend user@server:/path/to/app
pm2 start server.js --name voting-backend ```
- JWT per autenticazione admin
- Rate limiting su API
- Device fingerprinting anti-frode
- HTTPS in produzione obbligatorio
- Validazione input rigorosa
- CORS configurato
- Supporta fino a 350 connessioni simultanee
- Ottimizzazione immagini automatica
- Lazy loading componenti
- WebSocket per ridurre latenza
- Caching strategico
- Verifica URL backend in variabili ambiente
- Controlla CORS settings
- Firewall potrebbe bloccare WebSocket
- Device fingerprint salvato in localStorage
- Pulisci localStorage per reset
- Verifica ID sessione nell'URL
- Controlla che sessione sia attiva
- POST
/api/auth/login- Login admin - GET
/api/auth/verify- Verifica token
- GET
/api/sessions- Lista sessioni - POST
/api/sessions- Crea sessione - GET
/api/sessions/:id- Dettaglio sessione - POST
/api/sessions/:id/start- Avvia votazione - POST
/api/sessions/:id/stop- Ferma votazione
- POST
/api/votes- Registra voto - GET
/api/votes/check- Verifica se ha votato - GET
/api/votes/stats/:sessionId- Statistiche
- Fork il progetto
- Crea feature branch (`git checkout -b feature/AmazingFeature`)
- Commit modifiche (`git commit -m 'Add AmazingFeature'`)
- Push al branch (`git push origin feature/AmazingFeature`)
- Apri Pull Request
Distribuito sotto licenza MIT. Vedi `LICENSE` per info.
Email: team@esempio.com Progetto: https://github.com/tuousername/voting-platform ```
/**
* Script per creare admin iniziale
*/
require('dotenv').config();
const bcrypt = require('bcryptjs');
const admin = require('firebase-admin');
// Inizializza Firebase Admin
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n')
})
});
const db = admin.firestore();
async function seedAdmin() {
try {
const email = process.env.ADMIN_EMAIL || 'admin@esempio.com';
const password = process.env.ADMIN_PASSWORD || 'changeme123';
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Crea admin
await db.collection('admins').doc('default-admin').set({
email,
password: hashedPassword,
name: 'Admin',
role: 'admin',
createdAt: new Date()
});
console.log('β
Admin creato con successo');
console.log(`π§ Email: ${email}`);
console.log(`π Password: ${password}`);
console.log('β οΈ IMPORTANTE: Cambia la password al primo accesso!');
} catch (error) {
console.error('β Errore creazione admin:', error);
} finally {
process.exit(0);
}
}
seedAdmin();