Progetto personale: non c'è un cliente, l'ho costruito per studio o per sperimentare.
Case study
- Il mio ruolo
- Tutto, da solo: prodotto, regole del verdetto, bot, test e deploy su Fly.io. Il codice l'ho scritto con Claude Code: io decido cosa costruire e come, e ogni modifica passa da typecheck e test prima di andare in produzione.
- Durata
- Da luglio ad agosto 2026
Il problema
Le app di previsioni per il vento danno già tutti i numeri: nodi, raffiche, direzione, onda. Non dicono se si esce. Chi arriva a Tarifa da fuori non sa ancora leggerli per quello spot, e una giornata buona per un esperto può non esserlo per un principiante. Serviva una risposta sola, con un perché di cui fidarsi. I vincoli erano concreti. Il piano gratuito di Goable concede 50 chiamate al giorno e non accetta il livello del rider. Il lancio copre un solo spot. Il bot deve girare come un solo processo, perché Telegram consegna gli aggiornamenti a un solo processo alla volta e i dati stanno in un file SQLite.
Cosa ho fatto e perché
- Il verdetto prima dei numeri: ogni messaggio apre con il punteggio da 0 a 100, un colore (verde, giallo o rosso) e le ore migliori, cioè il blocco continuo di ore sopra il 90% del picco. Contano solo le ore tra le 8 e le 20, così un picco di vento alle 3 di notte non decide la giornata. Una riga dice se domani migliora, peggiora o resta uguale.
- Il perché in una riga: i tre fattori che pesano di più nel punteggio di Goable, ognuno con un giudizio semplice, per esempio "wind poor · wind dir good · wave good". Il tasto Why? elenca tutti i fattori con la loro percentuale.
- Una soglia per livello, un no-go per tutti: il piano gratuito di Goable non accetta il livello del rider, quindi il bot lo applica sul punteggio. Per dire "vai" servono 75 punti a un principiante, 65 a un intermedio e 55 a un esperto. Se Goable segnala che uscire è impossibile o pericoloso, per esempio perché manca il vento, il verdetto è no-go qualunque sia il livello. Il bot segue il segnale esplicito dell'API, così una giornata di vento forte non diventa un falso no-go.
- Chiamate per spot, non per utente: ogni 12 ore il bot aggiorna Tarifa con due chiamate a Goable, la serie oraria di oggi e domani e il dettaglio del picco di oggi, e salva tutto in SQLite. Comandi, tasti e brief leggono solo da lì. Un contatore giornaliero, controllato prima di ogni chiamata, si ferma a 45. Un valore sbagliato nella configurazione blocca l'avvio invece di togliere il limite.
- Un brief al giorno, non di più: alle 7:00 ora di Tarifa ogni iscritto riceve il verdetto una volta sola, anche se il processo riparte. Chi ha bloccato il bot esce dagli iscritti. Se un aggiornamento salta, il bot non descrive la giornata con i dati di ieri: toglie il perché e, dopo 18 ore, avvisa che i dati non sono freschi.
- Misurare l'idea: il bot registra in SQLite i gesti che dicono se serve, come le aperture di Now, i tocchi su Why? e le condivisioni, senza dati personali oltre all'id di Telegram. Il verdetto da condividere porta un link al bot con un riferimento, così si contano i nuovi utenti che arrivano dai gruppi. Nei giorni da "vai" un tasto Book, non ancora attivo, misura chi vorrebbe prenotare.
- Un processo, deploy solo con i test verdi: su Fly.io il bot è un worker senza porte aperte, su una sola macchina legata a un solo volume, perché il long polling di Telegram e SQLite vogliono un processo solo. A ogni push su main, GitHub Actions lancia typecheck e i 22 test e solo dopo fa il deploy. Allo spegnimento cron, bot e database si chiudono in ordine entro 5 secondi. Dependabot propone gli aggiornamenti ogni settimana.
Risultati
- 1 giornodal primo commit al primo deploy automatico su Fly.io
- 4chiamate al giorno all'API di Goable, con qualsiasi numero di iscritti
- 0chiamate all'API per comandi, tasti e brief, letti dalla cache
- 3livelli di rider, ognuno con la sua soglia per il "vai"
- 07:00il brief di ogni mattina, una volta sola anche se il processo riparte
- 22test automatici, prima di ogni deploy
Stack in evidenza
- Node.js 22
- Typescript
- grammY
- Goable SDK
- SQLite (better-sqlite3)
- node-cron
- node:test
- Docker
- Fly.io
- Github Actions
Hai un progetto simile? Parliamone.
ScrivimiChi va a Tarifa apre la chat con @GoSignalApp_bot, sceglie il suo livello e ogni mattina alle 7:00 riceve il verdetto della giornata: punteggio, ore migliori, il perché in una riga e se per il suo livello conviene uscire. Durante il giorno può rivederlo quando vuole, aprire il dettaglio di ogni fattore, confrontare oggi con domani e girare il verdetto al gruppo con cui esce. Nei giorni senza vento il bot dice no-go a tutti, qualunque sia il livello.
Cosa porto a un'agenzia o a una PMI da questo progetto
- Un servizio in produzione il giorno stesso del primo commit, sviluppato con Claude Code, con typecheck e test che bloccano il deploy se qualcosa non va.
- I costi di un'API esterna sotto controllo per come è fatto il sistema: le chiamate dipendono dallo spot, non dagli utenti, e un tetto giornaliero le ferma.
- Dati tecnici tradotti in una decisione che una persona capisce: un verdetto, il perché in una riga, il dettaglio a un tocco.