Il brief: un QR, nessuna installazione, nessuna spiegazione.
L'occasione è Stregati dai Vicoli, tre giorni di mercatini, degustazioni e percorsi nel centro storico di Ponte, in provincia di Benevento, organizzati dalla Pro Loco di Ponte. Ho costruito l'app come contributo all'evento: tredici punti numerati sulla mappa, ciascuno con la sua scheda, il suo menu e il suo percorso.
I vincoli di un'app per un evento sono tutti scomodi. Chi la apre è per strada, spesso con una mano sola, al buio, in mezzo alla folla, con il campo che va e viene. Non la installerà, non si registrerà, e se non capisce in dieci secondi cosa fare se ne va. Questo scarta in partenza quasi tutto quello che si impara costruendo software gestionale: qui l'interfaccia è il prodotto, e il tempo che l'utente le concede è quasi nullo.
Ho scelto una web app statica, installabile ma non da installare, che funziona offline dopo la prima apertura. Niente server applicativo, niente database: i dati stanno in un file. Ne parlo più avanti, perché è la decisione che ha reso tutto il resto possibile.
La mappa è nata su un foglio di carta.
Il materiale di partenza era la fotografia di una piantina stampata, con i punti numerati a penna. Non c'era una mappa digitale con quei vicoli: Google Maps non li disegna come servono qui, e Street View, nel pieno di una festa, mostrerebbe un borgo che non c'è. Ho ridisegnato la mappa in vettoriale, isolato per isolato, in un sistema di coordinate mio: i pixel della fotografia.
Questa non è un'ottimizzazione, è una scelta di fondo. Una mappa disegnata a mano è un dato di input, non un asset grafico: da lì dipendono la posizione dei pin, i percorsi, perfino il collegamento con il GPS. E la prima versione della geometria era, di fatto, un'ipotesi: gli edifici tracciati a occhio, due isolati separati da una fessura che sulla mappa sembrava un vicolo e nella realtà era un muro continuo. Finché qualcuno che il posto lo conosce non lo guarda e dice "qui no", quello che hai non è una mappa. È un'opinione.
Il GPS sbaglia più di quanto sia lungo un vicolo.
Lo smartphone che indica "sei qui" è la funzione che l'utente si aspetta di più, ed è quella che fa più danno se sbaglia. In un vicolo stretto tra palazzi alti il segnale rimbalza e la posizione può scostarsi di cinque o dieci metri. Con due stand a sei metri l'uno dall'altro, il pallino blu può finire davanti a quello sbagliato.
Ho fatto tre cose. Prima, la calibrazione: ho misurato le coordinate GPS reali di alcuni punti noti, e le ho usate per calcolare la trasformazione che porta una coordinata geografica sulla mia mappa. Con cinque punti di riferimento, lo scarto medio sui punti stessi è sotto i due metri e mezzo. Seconda, la correzione del segnale: la posizione viene smorzata, e l'app mostra il cerchio di incertezza invece di fingere precisione. Terza, e più importante, un'alternativa che non dipende dal GPS: "sono all'ingresso", oppure "sono vicino al punto 3".
"Quando il sensore non è affidabile, la funzione deve avere un'uscita che non lo richieda."
C'è anche un vincolo che si scopre solo quando si pubblica: il browser concede la geolocalizzazione solo su connessioni HTTPS. In sviluppo non te ne accorgi, sul telefono il pulsante non fa nulla. Vale la pena saperlo prima di stampare i QR.
Il percorso più breve passa dove non si può passare.
"Portami qui" calcola il tragitto a piedi. Ho rappresentato i vicoli come un grafo, nodi nei punti dove una strada cambia o si incrocia, e ho usato l'algoritmo di Dijkstra per trovare il percorso più breve. La parte matematica richiede mezza pagina. Tutto il resto è la realtà.
Alla prima versione il tragitto da un punto all'altro attraversava un passaggio che esisteva solo nel mio grafo. Ho dovuto aprire un varco negli edifici nel disegno dove c'è una scala; ho dovuto chiudere un passaggio perché, per ragioni di sicurezza, durante la festa non si passa. E ho trovato un difetto classico: se l'utente era in mezzo a un vicolo, l'algoritmo lo agganciava al nodo più vicino, che stava "dietro", lo faceva tornare indietro e ripassare dallo stesso punto. Il pallino rimbalzava avanti e indietro. La correzione è stata agganciare partenza e arrivo al punto più vicino della strada, non al nodo.
La cosa che ha reso possibile sistemare tutto questo in fretta è stata una vista di controllo. Aggiungendo un parametro all'indirizzo, la mappa mostra i vicoli del grafo con i nomi dei nodi e le coordinate del punto toccato. Così chi conosce davvero il posto può guardarla sullo schermo e correggerla: "questo no, quello sì, qui passa".
Un algoritmo di percorso calcola il più breve tra i percorsi che gli hai descritto. Non sa quali sono veri.
Chi conosce il territorio è il vero revisore del software: serve uno strumento che gli permetta di vedere cosa il software ha capito, non di leggerlo.
I dati cambiano fino all'ultimo minuto.
Menu, prezzi, loghi, nomi degli stand: tutto è cambiato più volte in corsa, e quasi mai è arrivato in forma ordinata. Alcuni menu sono arrivati come fotografie di fogli scritti a mano; i prezzi sono rimasti a zero fino a quando non erano decisi; il punto 11 ha cambiato nome due volte e posizione una. Un'app che avesse i dati nel codice sarebbe stata ricompilata ogni mezz'ora.
Per questo tutto il contenuto sta in un solo file di dati, con una struttura volutamente semplice: un prodotto può essere solo un nome, oppure un nome con prezzo ed etichette. Un interruttore decide se i prezzi si vedono o no. Anche i filtri della pagina "cosa mangiare" nascono da lì: classificare i piatti (da mangiare seduti, da passeggio, dolci, bevande) è un lavoro da fare una volta sola, nel file, e l'interfaccia lo eredita. Cambiare un menu significa modificare una riga e ricaricare la pagina.
Offline, sole e folla: l'interfaccia deve funzionare con una mano.
Poche decisioni di interfaccia, tutte dettate dal contesto. Tema scuro, perché sera e schermi luminosi non si sposano. Pulsanti grandi, per chi cammina. Un'animazione discreta sui pin, perché l'utente "non sa che deve toccare" e il segnale deve nascere dall'interfaccia, non da un testo. Un benvenuto che porta l'attenzione sul menu, la funzione che quasi tutti cercano. E la regola di non muovere la mappa quando si tocca un punto: ogni volta che qualcosa si sposta da solo, l'utente perde l'orientamento.
E poi il funzionamento offline. Dopo il primo caricamento l'app vive nel telefono: se il campo cade nel vicolo più stretto, la mappa, il menu e il percorso continuano a funzionare. Per un'app per eventi è una funzione, non un dettaglio tecnico.
Hosting statico: non c'è un server da scalare.
La domanda che mi sono fatto più spesso è stata "e se arriva molta gente?". Con un'app senza server applicativo, la risposta è che non c'è niente che si possa saturare tranne la banda: sono file statici serviti da Apache, e dopo la prima visita il telefono li tiene da sé. Ho pubblicato l'app in una sottodirectory del sito, con una pagina di passaggio per il QR code.
Il difetto nascosto stava, come spesso accade, nella configurazione del sito. Il mio .htaccess blocca per sicurezza i file .json: giusto per il sito, fatale per un'app che legge i dati da un .json e il cui service worker ne usa un altro. Ho aggiunto un'eccezione nella cartella dell'app, e ho impostato la cache in modo che i dati vengano sempre riletti dal server mentre gli script, che hanno il nome con il codice di versione, restano in cache. Un nome come main-XXXX.js si può tenere un anno; un file di dati non si può tenere neanche un'ora.
Le statistiche le ho affidate a uno strumento che non usa cookie: conta le visite e pochi eventi (quali stand si toccano, quali percorsi si avviano) senza cookie e senza profilare nessuno. Per un'app di una festa di paese, è l'unica scelta sensata.
Cosa mi porto a casa.
- La mappa È un dato, non un disegno. La geometria vale quanto la verifica di chi conosce il posto.
- Il GPS Calibralo, mostra l'incertezza e prevedi sempre un'uscita che non lo richieda.
- I percorsi Un algoritmo corretto su un grafo sbagliato dà risposte sbagliate. Costruisci lo strumento per vedere il grafo.
- I dati Separali dal codice dal primo giorno: cambiano fino all'ultimo minuto.
- L'hosting Se non serve un server, non metterlo. La parte difficile è la configurazione, non la capacità.
Un'app per un evento è un progetto piccolo e breve, e proprio per questo mostra molto bene dove sta il lavoro: raramente nel codice, quasi sempre nelle decisioni che vengono prima. Se hai un borgo, una fiera, una sagra o un evento che merita una mappa, scrivimi. Puoi provare l'app qui.