Il problema
TotoMondiale è un gioco di pronostici gratuito che organizzo per i grandi tornei di calcio dalla metà degli anni Duemila. Il suo albo d’oro comprende TotoEuropeo 2008, TotoEuropeo 2012, TotoMondiale 2014 e TotoEuropeo 2016. Le regole sono cambiate poco: per ogni partita si compila una schedina, i punti seguono le quote e ogni schedina viene resa pubblica prima del fischio d’inizio, così nessuno può barare. Il vecchio sito in ASP classico non poteva dare ai giocatori quello che oggi si aspettano: leghe private con gli amici, una grafica comoda sul telefono e i risultati in diretta. Per i Mondiali 2026 l’ho riscritto da cima a fondo.
Cosa ho costruito
Una nuova piattaforma in Node.js che mantiene le vecchie regole e aggiunge leghe, dati live e un po’ di divertimento.
- Schedina da 9 coupon: risultato finale, primo tempo, goal/no goal, under/over, rigori, primo tempo/finale, pari/dispari, risultato esatto, gol totali. Le quote arrivano da API-Football, con quote predefinite quando non sono disponibili.
- Leghe private e pubbliche: ogni lega ha la sua classifica, il suo banner, la sua barra di notizie e la sua chat.
- Carte speciali: Sesto Senso dà un bonus sul risultato esatto, Malocchio toglie punti a un altro giocatore, Cornicello annulla un Malocchio.
- Fair play nel codice: le schedine e le carte degli altri restano nascoste finché la partita non si blocca, e la regola vale anche per gli amministratori della piattaforma. Se qualcuno dimentica una schedina, il sistema la compila a caso, proprio come dicevano le regole originali.
- Partite in diretta: un processo interroga API-Football ogni 30 secondi e aggiorna i risultati durante la gara.
- Funzioni AI: Claude scrive ogni giorno una serie di pronostici consigliati; gli amministratori di lega possono creare un banner con DALL-E 3 e un piccolo giornale della lega con OpenAI.
- Pagine del torneo e lingue: squadre, stadi, storia, fase a gironi e tabellone a eliminazione diretta, in cinque lingue, con accesso tramite Google.
Con cosa è fatto
Node.js 20, Express 4, EJS, MySQL 8, Passport con Google OAuth, Nodemailer e ImapFlow, su Phusion Passenger in cPanel. Rilascio a piccoli passi e aggiorno la versione ogni volta: il codice è alla versione 5.1.642, build 665. Le edizioni precedenti giravano in ASP classico con database Access.
Perché è fatto così
Gli orari d’inizio sono salvati in UTC, con uno scostamento separato per la visualizzazione. API-Football ha bisogno dell’ora UTC reale per trovare una partita, mentre i giocatori vogliono leggere l’ora italiana. Tenere separate le due cose elimina un’intera famiglia di bug, quelli in cui una partita si blocca un’ora prima o un’ora dopo.


