# Partite Alert — prototipo gratuito

App nuova e indipendente da Ricardo. Non è pubblicata online: lo ZIP contiene la versione da caricare su una nuova installazione Cloudflare Pages. Non contiene chiavi personali né usa credenziali di altre applicazioni.

## Cosa è pronto

Interfaccia italiana per telefono e computer, installazione sulla schermata Home, selezione di 22 categorie (prima e seconda divisione di 11 paesi), filtro regolabile, schede, quote prima osservate e live quando disponibili, registro avvisi, notifiche durante la sessione attiva, dimostrazione volontaria con squadre inventate. Motore backend con database durevole, deduplicazione, controllo budget e adattatore documentato per odss-api.com.

Il catalogo desiderato comprende Italia, Portogallo, Spagna, Francia, Inghilterra, Svizzera, Germania, Paesi Bassi, Danimarca, Scozia e Grecia. La presenza del selettore non significa copertura verificata. Nessuna delle 22 categorie né dei 10 operatori è garantita dalla sola installazione.

## Procedura dal telefono

1. Crea un account gratuito su https://odss-api.com oppure accedi al tuo. Controlla che il piano corrente offra ancora 500 richieste gratuite mensili e che non serva carta. Crea una chiave abilitata a **prematch e live / all**, calcio e mercati partita. Non attivare prove o piani a pagamento. L'offerta può cambiare.
2. Nel tuo account Cloudflare crea un progetto **Pages nuovo**, tramite caricamento diretto. Usa un nome distinto da Ricardo, per esempio Partite Alert. Carica **Partite_Alert_Web_Cloudflare.zip**. I file devono essere nella radice dello ZIP: index.html e _worker.js, non una cartella contenitore. Non caricare lo ZIP dei sorgenti come sito.
3. In Cloudflare, nella sezione Storage & databases / D1, crea un database distinto, ad esempio Partite Alert Dati. Non riutilizzare database di altre app. Nelle impostazioni del nuovo progetto Pages, aggiungi un binding D1 chiamato esattamente **DB** e seleziona il nuovo database.
4. Nelle impostazioni del progetto, variabili e segreti di produzione, aggiungi come **segreti**: **ODSS_API_KEY**, con la chiave del fornitore, e **APP_TOKEN**, con un codice lungo e casuale scelto da te (almeno 20 caratteri). Il primo resta solo sul server. Il secondo protegge l'accesso ai comandi dell'app: non condividere app e codice con estranei. Nessun altro segreto è necessario. Non mettere queste chiavi nei file o nei messaggi.
5. Ripubblica lo stesso ZIP dopo aver aggiunto binding e segreti. Apri l'indirizzo assegnato da Cloudflare. Nella sezione Fonte e copertura → Collega la tua installazione, inserisci il codice APP_TOKEN e premi **Inizializza database**. Questa operazione non azzera un budget esistente.
6. Premi **Verifica catalogo**: può consumare una richiesta. Vedi quali operatori italiani sono effettivamente riconosciuti dalla tua chiave e le loro disponibilità prematch/live. Le quote derivate vengono segnalate ed escluse dalla qualificazione.
7. Nelle associazioni guidate, scegli per ogni categoria soltanto il nome del fornitore di cui puoi verificare paese e divisione. Conferma la verifica e salva. Nomi generici come Super League, Championship, Premier League o Serie A possono essere condivisi da paesi diversi e sono disabilitati. Scegli un nome esplicitamente distinto e verificabile, se il catalogo ne offre uno. **Se non esiste una corrispondenza verificabile, quella categoria resta non supportata**; non basta riconoscere il nome di una squadra. Non associare lo stesso nome a due categorie.
8. Seleziona le categorie configurate, imposta i filtri, quindi premi **Aggiorna dati reali** prima dell'inizio delle partite. L'app deve aver osservato la quota prima del calcio d'inizio: avviarla quando una partita è già live non la qualifica retroattivamente.
9. Facoltativamente abilita notifiche e aggiornamento ogni 2 minuti. Mantieni la pagina visibile e attiva. Su iPhone le notifiche web possono richiedere l'aggiunta alla Home e una versione iOS compatibile; il funzionamento dipende dal browser. Gli avvisi nella pagina funzionano anche senza permesso notifiche.
10. Per installare: Android/Chrome → menu → Installa app/Aggiungi a schermata Home; iPhone/Safari → Condividi → Aggiungi alla schermata Home. HTTPS è necessario ed è fornito dall'indirizzo Pages.

I nomi delle voci Cloudflare possono variare. È necessario usare Pages con supporto al file _worker.js e binding D1; un hosting statico senza backend non basta. Se il caricamento mobile non accetta ZIP con Worker, carica la cartella estratta tramite desktop oppure usa Wrangler da un computer. Non è necessario acquistare un dominio.

## Come vengono selezionate le partite

Sul medesimo bookmaker italiano e sullo stesso mercato calcio 1X2 a 90 minuti:

- quota casa **strettamente inferiore** alla soglia scelta;
- quota ospite meno quota casa **maggiore o uguale** allo scarto impostato, normalmente 3;
- quote numeriche complete di 1, X e 2, non derivate da un altro operatore, e nessuna sospensione dichiarata;
- stato di sospensione conosciuto: un campo assente significa ignoto e non viene equiparato a «nessuna sospensione»;
- inizio effettivo indicato dal bookmaker noto e futuro, con lettura e cattura precedenti all'inizio;
- identificazione italiana esplicita (country IT e playable_it true), senza exchange o lane di mercati accessori.

Esempio: casa 1,25 e ospite 4,25 soddisfano lo scarto 3; con soglia 1,25 la partita è esclusa perché il confronto è stretto. Se due righe dello stesso operatore danno offerte ambigue, l'app non ne sceglie arbitrariamente una. Se l'orario viene modificato prima dell'inizio, la relativa prima osservazione viene ricatturata.

**Prima osservata non significa apertura.** L'adattatore registra la prima quota valida che l'app vede prima dell'inizio, insieme a data di cattura, lettura del fornitore e kickoff. Non legge uno storico. Il selettore «Apertura documentata» è previsto nel contratto del motore, ma con questa fonte non qualifica alcuna partita: nessuna apertura viene inventata. La scelta di usare la prima osservata deve essere compresa e accettata dall'utilizzatore.

La partita resta osservabile anche se le quote live cambiano. Il cambiamento delle quote non genera avvisi. Le quote live sono informazioni aggiuntive e possono essere assenti o sospese.

## Come funzionano gli avvisi

L'avviso descrive un **punteggio rilevato**, non un gol certificato istantaneamente. Serve una transizione osservata da casa non in svantaggio a casa in svantaggio, con quote prepartita qualificanti. Il primo risultato osservato già in svantaggio non genera avvisi. Il comportamento predefinito è un solo avviso per partita, persistito nel database; una scelta esplicita consente successivi passaggi dopo un pareggio o una rettifica VAR.

Il fornitore espone il punteggio corrente ma non il suo timestamp nativo. Per prudenza, la generazione dello snapshot deve avere al massimo 3 minuti, non essere futura e risultare coerente con stato live, motore live abilitato e minuto entro i tempi regolamentari, compreso 90+recupero. **Il timestamp delle quote non viene usato per provare la freschezza del punteggio.** Supplementari e rigori non sono accettati. L'API non documenta un flag VAR: l'app gestisce le rettifiche come modifiche successive del punteggio e non dichiara il gol convalidato.

L'adattatore usa una sola richiesta state=all per lettura. generated_at è la generazione più vecchia tra gli snapshot serviti: quote prepartita vecchie possono quindi sospendere gli avvisi anche se il live è più recente. È un limite deliberatamente prudente. Punteggi assenti, incoerenti, futuri, vecchi, risposte parziali e partite scomparse sospendono la baseline; la prima lettura utile dopo la ripresa non viene venduta come un nuovo gol. Se il server non osserva una partita per oltre 3 minuti, riprende con una nuova baseline. Tra due letture possono andare persi interi passaggi di punteggio.

La deduplicazione è salvata prima della risposta. Se la connessione cade dopo il salvataggio e prima della consegna, l'avviso può essere perso: si privilegia l'assenza di duplicati. Non è una garanzia di consegna. Le notifiche di sistema contengono minuto e operatori/quote prima osservate; la scheda mostra le quote live disponibili.

## Gratis: ciò che è e non è possibile

Il codice non ha abbonamenti, non avvia acquisti né chiamate a servizi a pagamento. Richiede account gratuiti separati Cloudflare e odss-api. Devi verificare le loro condizioni e restare nei piani gratuiti. D1/Pages hanno proprie quote e limiti di risorse; l'app non protegge altri servizi presenti nel tuo account. Il codice usa solo la nuova app e il nuovo database.

Il server applica un limite di 450 richieste per finestra di 30 giorni, aggiornata usando le informazioni di quota del fornitore quando disponibili, e si ferma con 10 richieste residue note nell'account. Ogni tentativo è prenotato atomicamente prima di contattare il fornitore; anche errori possono consumare il contatore locale in modo prudente. Il budget si condivide tra tutti i dispositivi di questa installazione. L'uso della stessa chiave in altre app non è pienamente osservabile finché il fornitore non restituisce la quota aggiornata. Il periodo iniziale locale è prudente, non prova il residuo effettivo dell'account.

Una lettura usa normalmente una richiesta. Ogni aggiornamento è distanziato di almeno un minuto sul server. **450 richieste a intervalli di 2 minuti coprono circa 15 ore totali, non un mese continuo.** Usa aggiornamenti manuali o sessioni brevi scelte da te. La verifica del catalogo consuma anch'essa budget. Non esiste monitoraggio gratuito continuativo garantito per 22 categorie e 10 operatori.

Per contenere risorse e consumo, viene letta al massimo una pagina di 5.000 righe e vengono elaborate al massimo 250 partite per invocazione. Il server non segue automaticamente pagine aggiuntive. Se il feed è incompleto, troncato, con fonti parziali o oltre il limite, lo indica e disabilita gli avvisi per quella lettura. Le associazioni per paese devono essere verificate, non ricavate da sottostringhe. Le osservazioni locali vengono mantenute per circa due giorni. Non viene conservato un archivio storico di quote.

Non ci sono cron, processi in background, scheduler o Web Push remoto. A pagina chiusa, telefono sospeso, browser in background, rete assente o permessi negati non è promesso alcun avviso. Il service worker salva soltanto la struttura dell'app per riaprirla offline; le API e le chiavi non vengono memorizzate nella cache offline. Per notifiche a pagina chiusa servirebbe un'altra implementazione con scheduler server, gestione sottoscrizioni Web Push, rinnovo quote e relativo budget: non è inclusa.

## Operatori e limiti delle fonti

I dieci nomi desiderati sono SNAI, Sisal, Eurobet, Lottomatica, Goldbet, Betflag, bet365, Betfair, bwin e Planetwin365. Le chiavi di catalogo esatte vengono confrontate con paese IT e disponibilità italiana, senza confondere omonimi internazionali o exchange. La presenza nel catalogo non garantisce quote per la singola partita, lega, mercato o fase live. Il dato può provenire da un feed partner. Quote con derived_from sono indicate come derivate e non qualificano il bookmaker nominale; più marchi della stessa famiglia possono avere listini correlati e non sono considerati fonti indipendenti.

Fonti consultate il 19 ottobre 2026:

- https://odss-api.com e https://odss-api.com/openapi.json — contratto dell'adattatore; piano gratuito dichiarato da verificare al momento dell'iscrizione.
- https://odss-api.com/api/v1/status e https://odss-api.com/api/v1/coverage — metadati pubblici generali, non prove di copertura per le 22 categorie.
- https://odss-api.com/api/v1/leagues?sport=calcio — nomi effettivamente pubblicati. Non espone il paese in modo strutturato, quindi alcune associazioni restano impossibili da garantire.
- https://www.api-football.com/pricing — alternativa studiata, 100 richieste al giorno dichiarate; NON integrata in questo pacchetto. Copertura attuale e operatori desiderati non verificati.
- https://the-odds-api.com — alternativa studiata, non integrata; storico non incluso nel gratuito e operatori italiani non garantiti.
- https://odds-api.io/pricing/free — servizio diverso da odss-api.com: le nuove chiavi gratuite risultavano sospese. Non è la fonte usata da questa app.

Non vengono chiamati endpoint mock, storico non attivo o stream riservati a piani a pagamento nella modalità reale. La demo contiene esclusivamente dati inventati e viene avviata volontariamente.

## Verifica eseguita e limiti residui

Test automatici di regole e integrazione con risposte simulate: soglia stretta, differenza aritmetica e precisione decimale, confronto di orari/fusi, origini quote, cattura prima del kickoff, sospensioni/derivate, identità partita, prima lettura dietro, passaggi successivi/VAR, dedup persistita, dati vecchi/parziali, autorizzazione, associazioni e budget atomico. Database SQLite reale usato per simulare l'interfaccia D1.

Non sono state usate chiavi reali, consumate quote personali, effettuate pubblicazioni né verificati risultati live. Non è stato effettuato un collaudo visuale con browser automatizzato o una prova su telefono. Il contratto HTTP è documentato e testato con mock, ma le risposte reali, i permessi del piano, la licenza d'uso dei dati e le associazioni campionato restano da verificare nel proprio account. Prima di affidarsi agli avvisi, confronta una partita reale con la fonte e usa la demo per verificare notifiche e comportamento.

## Sorgenti e modifiche

Sorgenti separati nella cartella partite-alert e nello ZIP Partite_Alert_Web_Cloudflare_Sorgenti.zip. Richiedono Node moderno (test con Node 24 e node:sqlite). Comandi dalla cartella: `node build.mjs` rigenera public/_worker.js, `npm test` esegue i test senza rete. Per ripubblicare, ricrea lo ZIP con il contenuto di public nella sua radice. Non modificare solo _worker.js: viene generato da worker-source.js e public/engine.js.

Il mapping può essere gestito nell'app. Per amministratori esperti, la variabile LEAGUE_MAP può sovrascrivere singole associazioni con oggetti {name, countryVerified:true}; i nomi ambigui restano esclusi. Non inserire dati di accesso in questo JSON. La versione caricata non richiede questa variabile.


## Aggiornamento grafico web

La versione aggiornata aggiunge dashboard scura, bandiere locali per 11 paesi e 22 categorie, identità dei dieci operatori e un catalogo iniziale di nove stemmi reali. Il matching richiede nome o alias esatto e paese verificato; nessuna copertura completa viene dichiarata. Squadre non riconosciute: scudo di iniziali etichettato simbolo generico. La demo usa tre partite inventate e stemmi propri dichiarati. I loghi non sono una prova di disponibilità dei dati.

Le immagini sono locali e non richiedono chiamate a terzi durante l’uso. Provenienza, alias e limiti sono elencati in /assets.html, /assets/manifest.json e /assets/teams/catalog.json. Il catalogo usa TheSportsDB come fonte; identità controllata, attualità grafica e diritti non certificati. Per un aggiornamento di un’installazione esistente mantenere DB, segreti e progetto Partite Alert, quindi ricaricare lo ZIP senza azzerare nulla. Chiudere e riaprire le schede se la precedente versione del service worker resta attiva. La nuova versione non è già online e non modifica Ricardo.
