Files
CRAPP/docs/modules/collegamento-csi.md
T
davideandClaude Sonnet 5 85223baa9d Formatta la documentazione con prettier
Solo whitespace: tabelle allineate, enfasi normalizzata (* -> _), a capo
coerenti. Nessuna modifica di contenuto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 13:38:56 +02:00

4.5 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 (503 solo 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. Con CSI_LIVE=1 verifica 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, /classifica mostra i dati esistenti come prima.
  • Portabilità (DD-013): endpoint HTTP standard, nessun servizio esclusivo.

Limiti noti

  1. La classifica si legge da HTML. Se il portale cambia la struttura della tabella il parsing restituisce un array vuoto e l'app ricade sui dati demo — non si rompe, ma i dati sono vecchi. Il check con CSI_LIVE=1 serve a scoprirlo.
  2. project_id è legato alla stagione. Per il 2026/27 servirà un nuovo id, ricavabile da team_details.php?team_id=3359, che elenca i campionati della squadra. Oggi va aggiornato a mano in csi-core.ts.
  3. 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).
  4. 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.