I dati dimostrativi in crapp-data.ts sono stati rimossi (DD-015); il fallback reale oggi è classifica vuota (o ultimo dato in cache) e risultati dallo Scout Live locale. Co-Authored-By: Claude Mythos <noreply@anthropic.com>
4.8 KiB
Modulo — Collegamento CSI
Stato: implementato (stagione 2025/26)
Route interessata: /classifica
Obiettivo
Mostrare nell'app la classifica e i risultati ufficiali del campionato CSI, al posto
dei dati dimostrativi hardcoded in crapp-data.ts. Nessun inserimento manuale da parte
degli amministratori: è esattamente il tipo di lavoro amministrativo che CrAPP deve togliere.
Sorgente dati
Portale Livescore CSI Bologna (https://livescore.csibologna.it).
Il portale non espone un'API pubblica documentata. Vengono usati gli stessi endpoint che il sito chiama internamente via ajax: sono raggiungibili senza autenticazione e senza API key, ma non offrono alcuna garanzia di stabilità.
| Endpoint | Formato | Uso |
|---|---|---|
components/project-sheets.php?project_id=767 |
HTML | Classifica completa dei due gironi |
assets/json/getEventsByTeamId.php?team_id=3359 |
JSON | Tutte le gare della squadra: data, ora, avversario, campo, risultato, parziali |
Altri endpoint disponibili ma non usati: getEventsByProjectIdHierarchical.php (tutte le
gare del campionato), project-chart-rankings.php (solo punti), project-next_matches.php,
project-last_results.php, team-roster.php, team-results.php.
Identificativi (stagione 2025/26)
| Cosa | Valore |
|---|---|
| Campionato | PVM - Campionato Open Misto Eccellenza |
project_id |
767 |
| Squadra sul portale | C.R.A.P. Volley (con i punti) |
team_id |
3359 |
| Girone | B |
Gli identificativi sono costanti in src/lib/csi-core.ts.
Implementazione
CSI (portale)
↓ fetch server-side, cache 6 ore
/api/public/csi → src/routes/api/public/csi.ts
↓ JSON { classifica, partite, girone, aggiornato }
useCsi() → src/lib/csi.ts (React Query, staleTime 6h)
↓
/classifica → src/routes/classifica.tsx
src/lib/csi-core.ts— costanti, tipi e funzioni pure:parseClassifica()(HTML → righe),partiteDaEventi()(JSON → partite),isNostraSquadra(),partiteGiocate().src/routes/api/public/csi.ts— unica route che contatta il CSI. Cache in memoria di 6 ore; in caso di errore restituisce l'ultimo dato buono (503solo se non ne esiste uno).src/lib/csi.ts— hook client, una lettura per sessione.src/lib/csi-core.test.ts— check del parsing:bun src/lib/csi-core.test.ts. ConCSI_LIVE=1verifica anche gli endpoint reali.
Regole rispettate
- Nessuna chiamata dal browser: il portale viene contattato solo lato server, al massimo 4 volte al giorno, indipendentemente da quanti giocatori aprono l'app (regola anti-consumo).
- Nessuna dipendenza nuova: parsing con espressioni regolari sulla struttura della tabella.
- Fallback: se il CSI non risponde, l'endpoint
/api/public/csirestituisce l'ultimo dato buono in cache; se non ne ha ancora uno, la classifica resta vuota e i risultati ricadono sulle partite dello Scout Live locale (useScoutMatches()). - Portabilità (DD-013): endpoint HTTP standard, nessun servizio esclusivo.
Limiti noti
- La classifica si legge da HTML. Se il portale cambia la struttura della tabella il
parsing restituisce un array vuoto:
/classificanon si rompe, ma mostra "Classifica non ancora disponibile" (o l'ultimo dato buono in cache, se ce n'è uno) e i risultati ricadono sulle partite dello Scout Live locale, non su dati demo — non esistono più incrapp-data.ts. Il check conCSI_LIVE=1serve a scoprire il problema di parsing. project_idè legato alla stagione. Per il 2026/27 servirà un nuovo id, ricavabile dateam_details.php?team_id=3359, che elenca i campionati della squadra. Oggi va aggiornato a mano incsi-core.ts.- La cache vive nel processo del server. Si perde a ogni cold start e non è condivisa tra
istanze. Sufficiente per una squadra; se serve di più, spostare i dati in una tabella
Supabase riempita da un job cron (stesso pattern di
promemoria-palloni). - I risultati includono anche la Coppa, non solo il girone di campionato.
Evoluzioni possibili
- Prossima partita ufficiale nella home e nel calendario (i dati sono già disponibili).
- Creazione automatica degli eventi partita da calendario CSI.
- Confronto tra i parziali ufficiali e quelli dello Scout Live.