Compare commits
7
Commits
feature/gara
...
v1.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7b9affbd6 | ||
|
|
7acdc2ba1e | ||
|
|
c1627a0720 | ||
|
|
63d1f01be6 | ||
|
|
2787672cd5 | ||
|
|
1c63808bfb | ||
|
|
92ce3979a3 |
No files matched your search
+10
-16
@@ -9,9 +9,9 @@ schema in [docs/DATABASE.md](docs/DATABASE.md), le procedure in
|
||||
|
||||
## Stato generale
|
||||
|
||||
- **Versione:** 1.5.0 su `main` (tag `v1.5.0`): campionato CSI sulla stagione 2026/27 (nuovi `project_id`
|
||||
e `team_id`, nessuna Coppa). Su `feature/gara` c'è del lavoro non ancora rilasciato (voto MVP, vedi
|
||||
«Lavoro in corso»). La 1.4.2: ogni evento può avere un link Google Maps del luogo, mostrato come
|
||||
- **Versione:** 1.6.0 su `main` (tag `v1.6.0`), pubblicata il 02/11/2026: voto MVP definitivo, segreto e a
|
||||
tempo (DD-051, DD-052) e Scout live a valutazioni − / + (DD-053). La 1.5.0: campionato CSI sulla stagione 2026/27 (nuovi `project_id` e `team_id`,
|
||||
nessuna Coppa). La 1.4.2: ogni evento può avere un link Google Maps del luogo, mostrato come
|
||||
«Apri su Maps» nelle schede (`m34`). La 1.4.1: gli eventi con convocati si
|
||||
vedono solo ai convocati (admin e allenatori sempre) e «Rosa e presenze» elenca solo loro. La 1.4.0:
|
||||
avviso «Presenza modificata» ad admin e allenatori (DD-050, `m32`-`m33`). La 1.3.1: il Calendario
|
||||
@@ -21,25 +21,19 @@ schema in [docs/DATABASE.md](docs/DATABASE.md), le procedure in
|
||||
[docs/CHANGELOG.md](docs/CHANGELOG.md).
|
||||
- **Backend:** Supabase proprietario (`kfkcldwncxqaixetsjes`). Lovable Cloud e il vecchio
|
||||
Project Ref `hetycilxgkdmccelwerq` non si usano più.
|
||||
- **Migration:** 50 file in `supabase/migrations/`, fino a `m39_scout_valutazioni`. In produzione
|
||||
sono applicate 45 su 50, fino alla `m34_link_maps_evento` (verificato con
|
||||
`npx supabase migration list --linked` il 26/10/2026: le uniche mancanti sono `m35`-`m39`, nessuna
|
||||
migration remota è assente dal repository). **Da applicare ancora: `m35`-`m39`**
|
||||
(voto MVP e badge social, DD-051 e DD-052, valutazioni dello scout, DD-053; branch `feature/gara`): `npx supabase db push` è rinviato
|
||||
per scelta, non è stato eseguito. Vanno applicate subito prima del rilascio del codice: con le sole
|
||||
migration il voto MVP dell'app in produzione (1.4.2) smette di funzionare, con il solo codice la
|
||||
vista dei conteggi non esiste.
|
||||
- **Migration:** 50 file in `supabase/migrations/`, fino a `m39_scout_valutazioni`. In produzione sono
|
||||
applicate tutte e 50 (`npx supabase db push` del 02/11/2026: `m35`-`m39`, verificato con
|
||||
`npx supabase migration list --linked`; nessuna migration remota è assente dal repository). Prima
|
||||
del push è stato salvato lo schema di produzione (solo schema, non i dati).
|
||||
- **Worker delle notifiche** (`mailer/`): in funzione su un Raspberry Pi con Docker dal 29/09/2026
|
||||
([docs/WORKER_EMAIL.md](docs/WORKER_EMAIL.md)). Il codice con l'interruttore «Email» in Profilo
|
||||
è su `main` dalla 1.3.0.
|
||||
- **Accesso:** il login Google è l'unica via d'ingresso; i permessi di amministrazione arrivano
|
||||
solo da `user_roles`. Il collegamento degli account è un processo continuo: ogni giocatore si
|
||||
collega al primo accesso (DD-018).
|
||||
- **Lavoro in corso:** branch `feature/gara` per le funzioni di gara (correzioni e nuove
|
||||
funzioni; in futuro anche lo scouting). Primo lavoro: il voto MVP definitivo, segreto, a tempo e
|
||||
tra presenti, con i pari merito (DD-051, DD-052). Poi lo scout live ridotto alle valutazioni − / +
|
||||
per set (DD-053), salvate subito su database. Non ancora in `main`, non rilasciato, versione
|
||||
invariata. Le altre voci aperte stanno in [docs/ROADMAP.md](docs/ROADMAP.md), sotto «Prossimo».
|
||||
- **Lavoro in corso:** nessuno su branch. Le voci aperte stanno in [docs/ROADMAP.md](docs/ROADMAP.md), sotto
|
||||
«Prossimo». Da decidere sullo scout: il pulsante «Annulla» in alto agisce solo sulle azioni, che non
|
||||
si creano più, quindi è sempre spento.
|
||||
|
||||
## Cose da sapere
|
||||
|
||||
|
||||
+11
-3
@@ -13,7 +13,10 @@ versioni `0.y.z` erano pre-release.
|
||||
|
||||
## [Non rilasciato]
|
||||
|
||||
Cinque migration, da `m35` a `m39`, **non ancora applicate in produzione**.
|
||||
## [1.6.0] - 2026-11-02
|
||||
|
||||
Voto MVP definitivo e segreto, Scout live a valutazioni. Cinque migration, da `m35` a `m39`,
|
||||
applicate in produzione il 02/11/2026.
|
||||
|
||||
### Aggiunto
|
||||
|
||||
@@ -23,14 +26,16 @@ Cinque migration, da `m35` a `m39`, **non ancora applicate in produzione**.
|
||||
|
||||
### Modificato
|
||||
|
||||
- Scout live: tolti i tasti dei punti, il tabellone del punteggio e il blocco avversario / in casa /
|
||||
trasferta; resta la scelta del giocatore e la valutazione − / + per set
|
||||
- Scout live: tolti i tasti dei punti, il tabellone del punteggio, l'elenco «Ultime azioni» e il
|
||||
blocco avversario / in casa / trasferta; resta la scelta del giocatore e la valutazione − / + per set
|
||||
([DD-053](decisions/DD-053.md)). «Chiudi set» e «Fine partita» funzionano anche senza punti; le
|
||||
partite di sole valutazioni non compaiono come risultato in Home, Classifica e pagina partita.
|
||||
- Scout live: il salvataggio è immediato a ogni tocco (prima c'era una pausa di 0,8 secondi) e,
|
||||
se non riesce, compare un avviso.
|
||||
- Scout live: la griglia «Selezione giocatore» si ordina per cognome o per numero; nel riquadro di
|
||||
ogni giocatore compaiono i + del set in corso (ricezione esclusa) al posto dei punti.
|
||||
- Scout live: dopo «Fine partita» il messaggio dice solo «Partita salvata» (il voto MVP apre 2 ore
|
||||
dopo l'inizio della partita, non dipende dallo scout).
|
||||
- Il voto MVP è definitivo ([DD-051](decisions/DD-051.md)): si sceglie un nome, si conferma e non si
|
||||
può più cambiare. Il database lo impone (solo gli admin possono correggere un voto).
|
||||
- In caso di parità in testa gli MVP sono più d'uno: ognuno dei pari merito conta un titolo, e in
|
||||
@@ -41,6 +46,9 @@ Cinque migration, da `m35` a `m39`, **non ancora applicate in produzione**.
|
||||
- La votazione MVP si chiude 24 ore dopo l'apertura (cioè 26 ore dopo l'inizio della partita): le
|
||||
partite più vecchie non si votano più.
|
||||
|
||||
- I test non pretendono più una gara CSI già giocata: a inizio stagione il calendario c'è ma i
|
||||
risultati no (un test si salta finché non c'è una gara giocata).
|
||||
|
||||
### Sicurezza
|
||||
|
||||
- Il database impone anche le regole che prima valevano solo nell'app: il voto MVP è possibile solo per
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ il campionato. Dove serve il dettaglio c'è il rimando al modulo.
|
||||
| **Badge** | Riconoscimenti calcolati a runtime, mai salvati (DD-007): normali (bronzo/argento/oro), segreti, social (votati dai compagni). Vedi [modules/badge.md](modules/badge.md). |
|
||||
| **Cacche** | Sondaggio pre-partita (`cacche_partita`) usato per statistiche e per il badge segreto `s-cacche`. |
|
||||
| **Palloni** | Turno a rotazione di chi porta e riporta i palloni a partite e allenamenti. Vedi [modules/palloni.md](modules/palloni.md). |
|
||||
| **Scout / Scout Live** | Rilevazione in tempo reale delle azioni di una partita, con blocco condiviso («Scout occupato da X»). Solo statistiche di squadra, mai classifiche individuali (DD-008). |
|
||||
| **Scout / Scout Live** | Rilevazione in tempo reale, durante la partita, delle valutazioni − / + di ogni convocato su battuta, ricezione, attacco e muro, per set (DD-053), con blocco condiviso («Scout occupato da X»). Solo statistiche di squadra, mai classifiche individuali (DD-008). |
|
||||
| **CSI** | Centro Sportivo Italiano, l'ente del campionato. Due usi: il **tesseramento** dei giocatori (manuale, DD-009) e il **collegamento** con classifica e risultati ufficiali ([modules/collegamento-csi.md](modules/collegamento-csi.md)). |
|
||||
| **Stagione CSI** | Si ricava dalle date delle gare, non da un'impostazione (DD-032). |
|
||||
| **Centro notifiche** | Storico in-app (`notifiche_utente`) sull'avatar del profilo, separato dalla push (DD-030). |
|
||||
|
||||
@@ -230,7 +230,8 @@ DettaglioCsiEsteso → src/components/crapp/DettaglioCsi.tsx (formazio
|
||||
tabella/lista, sia per classifica/partite sia per formazioni/precedenti.
|
||||
- **Fallback**: se il CSI non risponde, l'endpoint `/api/public/csi` restituisce 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()`).
|
||||
ricadono sulle partite dello Scout Live che hanno un punteggio (`useScoutMatches()` filtrato con
|
||||
`haPunteggio()`: quelle di sole valutazioni non sono un risultato).
|
||||
`/api/public/csi-partita/$id` non ha questo fallback sulla prima chiamata per una gara mai
|
||||
vista (vedi sopra): fallisce con `503`, e la UI (`DettaglioCsiEsteso`) semplicemente non
|
||||
mostra la sezione formazioni/scontri diretti, senza rompere il resto della pagina.
|
||||
@@ -243,7 +244,7 @@ DettaglioCsiEsteso → src/components/crapp/DettaglioCsi.tsx (formazio
|
||||
1. **La classifica si legge da HTML.** Se il portale cambia la struttura della tabella il
|
||||
parsing restituisce un array vuoto: `/classifica` non 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ù in `crapp-data.ts`.
|
||||
sulle partite dello Scout Live con punteggio, non su dati demo — non esistono più in `crapp-data.ts`.
|
||||
Il check con `CSI_LIVE=1` serve a scoprire il problema di parsing.
|
||||
2. **`project_id` e `team_id` sono legati alla stagione.** Per il 2027/28 serviranno due nuovi
|
||||
id (vedi "Sorgente dati" sopra per come ritrovarli): vanno aggiornati a mano in
|
||||
|
||||
+27
-22
@@ -1,6 +1,6 @@
|
||||
# Modulo — Scout Live
|
||||
|
||||
**Stato:** implementato (fix M7 per la persistenza condivisa)
|
||||
**Stato:** implementato (fix M7 per la persistenza condivisa; valutazioni − / + dalla 1.6.0, DD-053)
|
||||
**File principali:** `src/lib/scout-live.ts`, `src/lib/scout-stato.ts`, `src/lib/scout-store.ts`,
|
||||
`src/lib/scout-export.ts`, `src/lib/cacche.ts`, `src/components/crapp/ScoutEntry.tsx`,
|
||||
`src/components/crapp/SondaggioCacche.tsx`, `src/routes/scout.tsx`, `src/routes/partita.$id.tsx`
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
Permettere a un solo referente per volta di registrare in tempo reale, durante la partita,
|
||||
un giudizio − / + sui fondamentali (battuta, ricezione, attacco, muro) di ciascun convocato,
|
||||
per set, con salvataggio condiviso su Supabase (non più solo `localStorage`, fix M7) così che tutta la squadra veda lo stato
|
||||
aggiornato da qualunque dispositivo.
|
||||
per set, con salvataggio condiviso su Supabase (non più solo `localStorage`, fix M7) così che chi
|
||||
riprende lo scout trovi lo stato aggiornato, da qualunque dispositivo.
|
||||
|
||||
---
|
||||
|
||||
@@ -20,10 +20,9 @@ aggiornato da qualunque dispositivo.
|
||||
|
||||
- `scout_sessioni` — chi ha il controllo dello Scout Live per una partita (una riga per
|
||||
`evento_id`, quindi un solo detentore).
|
||||
- `scout_live` — stato in corso (azioni non ancora concluse) di una sessione.
|
||||
- `scout_live` — stato in corso (valutazioni, set chiusi, avversario e campo) di una sessione.
|
||||
- `scout_partite` — archivio delle partite scoutate concluse (risultato, parziali, azioni,
|
||||
valutazioni − / +),
|
||||
mai più modificato una volta salvato (solo eliminabile per intero).
|
||||
valutazioni − / +), mai più modificato una volta salvato (solo eliminabile per intero).
|
||||
- `cacche_partita` — sondaggio goliardico pre-partita, un voto per giocatore/evento
|
||||
(`UNIQUE evento_id, giocatore_id`).
|
||||
|
||||
@@ -66,14 +65,20 @@ perché occupava spazio 6 giorni su 7.
|
||||
|
||||
## Cosa registra
|
||||
|
||||
La schermata `/scout` ha due passi: **Selezione giocatore** (griglia dei convocati, ordinata per cognome o per numero con il selettore a destra del titolo, default cognome; in ogni riquadro, sotto il nome, i **+** del giocatore nel set in corso, ricezione esclusa; filtrati sulle
|
||||
risposte "presente"/"ritardo", con fallback a tutta la rosa se nessuno ha risposto) e **2. Valuta**
|
||||
(vedi sotto), seguiti da «Ultime azioni», «Chiudi set» e «Fine partita». Salvataggio automatico su
|
||||
`scout_live` **a ogni cambiamento**, senza attesa: i salvataggi vanno in coda, uno alla volta e in ordine, e ognuno scrive lo stato intero (uno riuscito rimedia a uno fallito). Se un salvataggio non riesce compare un avviso fisso che sparisce al salvataggio successivo riuscito.
|
||||
La schermata `/scout` ha due passi: **Selezione giocatore** e **Valuta** (vedi sotto), seguiti da
|
||||
«Chiudi set» e «Fine partita».
|
||||
|
||||
- **Selezione giocatore:** griglia dei convocati (chi ha risposto "presente"/"ritardo", con fallback
|
||||
a tutta la rosa se nessuno ha risposto), ordinata per cognome o per numero con il selettore a
|
||||
destra del titolo (default cognome). In ogni riquadro, sotto il nome, compaiono i **+** del
|
||||
giocatore nel set in corso, ricezione esclusa (`contaPiuSenzaRicezione()`).
|
||||
- **Salvataggio** su `scout_live` a ogni cambiamento, senza attesa: i salvataggi vanno in coda, uno
|
||||
alla volta e in ordine, e ognuno scrive lo stato intero (uno riuscito rimedia a uno fallito). Se
|
||||
un salvataggio non riesce compare un avviso fisso, che sparisce al salvataggio successivo riuscito.
|
||||
|
||||
**Punteggio e azioni.** L'interfaccia non registra più il punteggio: sono stati tolti i tasti delle
|
||||
azioni (punto attacco, ace, muro, errore nostro, punto e errore avversario), il tabellone con punti
|
||||
e set e il blocco avversario / in casa / trasferta. Avversario e campo restano quelli ricavati dal
|
||||
e set, l'elenco «Ultime azioni» e il blocco avversario / in casa / trasferta. Avversario e campo restano quelli ricavati dal
|
||||
titolo della partita (o dallo stato già salvato) e non si modificano. I tipi di azione
|
||||
(`AzioneTipo`, `scout-store.ts`: `attacco`, `ace`, `muro`, `errore`, `punto_avv`, `errore_avv`),
|
||||
i totali `totaliPerGiocatore()` e il campo `scout_partite.azioni` restano nel codice e nei dati:
|
||||
@@ -85,10 +90,10 @@ leggono le partite scoutate prima di questa modifica, ma oggi nessuna schermata
|
||||
|
||||
Per ogni convocato lo scout può segnare un **−** o un **+** su battuta, ricezione, attacco e muro
|
||||
([DD-053](../decisions/DD-053.md)). Non sono punti: restano fuori dal punteggio, dai parziali e dai
|
||||
totali P/A/M/E. Si seleziona il giocatore (primo passo) e si tocca − o + sul fondamentale (passo 2, il cui titolo mostra
|
||||
cognome e numero del giocatore e il set in corso);
|
||||
accanto a ogni tasto compare il conteggio di quel giocatore **nel set in corso**. «Annulla» nella
|
||||
sezione toglie l'ultima valutazione del set in corso (l'«Annulla» in alto agisce solo sulle azioni, quindi oggi è sempre spento).
|
||||
totali P/A/M/E. Si seleziona il giocatore e si tocca − o + sul fondamentale: il titolo della sezione
|
||||
mostra cognome e numero del giocatore e il set in corso, e accanto a ogni tasto compare il conteggio
|
||||
di quel giocatore **nel set in corso**. «Annulla» nella sezione toglie l'ultima valutazione del set in
|
||||
corso (l'«Annulla» in alto agisce solo sulle azioni, quindi oggi è sempre spento).
|
||||
|
||||
Ogni tocco è una riga `Valutazione` (`giocatoreId`, `fondamentale`, `segno`, `set`, `ts`) in una
|
||||
lista separata da `azioni`; i conteggi per set si calcolano con `contaValutazioni()`
|
||||
@@ -114,11 +119,10 @@ e rilascia la sessione.
|
||||
|
||||
## Export CSV
|
||||
|
||||
`scout-export.ts` genera un CSV (separatore `;`, BOM UTF-8) con parziali, riepilogo per
|
||||
giocatore e log cronologico delle azioni. Se ci sono valutazioni, aggiunge una tabella per set e giocatore con i
|
||||
|
||||
- e i − di ogni fondamentale (solo per chi ne ha). Scaricabile dagli admin dalla pagina partita,
|
||||
sezione "Report tecnico".
|
||||
`scout-export.ts` genera un CSV (separatore `;`, BOM UTF-8) con parziali, riepilogo per giocatore e
|
||||
log cronologico delle azioni. Se ci sono valutazioni, aggiunge una tabella per set e giocatore con
|
||||
i conteggi di «più» e «meno» di ogni fondamentale (solo per chi ne ha). Scaricabile dagli admin dalla
|
||||
pagina partita, sezione "Report tecnico".
|
||||
|
||||
---
|
||||
|
||||
@@ -139,7 +143,7 @@ calcolati a runtime).
|
||||
|
||||
## Regole rispettate
|
||||
|
||||
- **DD-008 (gamification equa)**: i dati tecnici (punti/ace/muri) restano confinati allo Scout
|
||||
- **DD-008 (gamification equa)**: i dati tecnici (punti/ace/muri e valutazioni) restano confinati allo Scout
|
||||
Live come statistica di squadra e non entrano nel tipo `Giocatore` usato per badge o
|
||||
classifiche individuali.
|
||||
|
||||
@@ -167,5 +171,6 @@ calcolati a runtime).
|
||||
|
||||
## Evoluzioni possibili
|
||||
|
||||
- Mostrare le valutazioni per set e giocatore nella pagina della partita (oggi solo nel CSV admin) e, nello scout, in sola lettura quelle dei set chiusi.
|
||||
- Mostrare le valutazioni per set e giocatore nella pagina della partita (oggi solo nel CSV admin)
|
||||
e, nello scout, in sola lettura quelle dei set chiusi.
|
||||
- Realtime (Supabase Realtime) per aggiornare la sessione condivisa senza refresh manuale.
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "crapp",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "crapp",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^2.111.0",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "crapp",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
|
||||
+1
-39
@@ -341,8 +341,6 @@ function ScoutBoard({
|
||||
const contiSelezionato = selezionato
|
||||
? contaValutazioni(valutazioni, selezionato, setCorrente)
|
||||
: null;
|
||||
const ultime = [...azioni].slice(-4).reverse();
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="sticky top-0 z-30 bg-hero px-5 pb-4 pt-6 text-primary-foreground">
|
||||
@@ -419,7 +417,7 @@ function ScoutBoard({
|
||||
<section className="px-5 pt-4">
|
||||
<div className="mb-2 flex items-center justify-between gap-2">
|
||||
<p className="text-[13px] font-bold uppercase tracking-wide text-muted-foreground">
|
||||
2. Valuta{giocatoreSel ? ` ${giocatoreSel.cognome} - ${giocatoreSel.numero}` : ""} · Set{" "}
|
||||
Valuta{giocatoreSel ? ` ${giocatoreSel.cognome} - ${giocatoreSel.numero}` : ""} · Set{" "}
|
||||
{setCorrente}
|
||||
</p>
|
||||
<button
|
||||
@@ -469,42 +467,6 @@ function ScoutBoard({
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="px-5 pt-4">
|
||||
<div className="rounded-3xl bg-card p-3 shadow-card">
|
||||
<p className="text-[13px] font-bold uppercase tracking-wide text-muted-foreground">
|
||||
Ultime azioni
|
||||
</p>
|
||||
{ultime.length === 0 ? (
|
||||
<p className="mt-2 text-[13px] text-muted-foreground">Nessuna azione registrata.</p>
|
||||
) : (
|
||||
<ul className="mt-2 space-y-1.5">
|
||||
{ultime.map((a, i) => {
|
||||
const g = rosa.find((x) => x.id === a.giocatoreId);
|
||||
return (
|
||||
<li
|
||||
key={a.id}
|
||||
className={cn(
|
||||
"flex items-center justify-between gap-2 px-1 text-[13px]",
|
||||
i === 0 && "anim-riga",
|
||||
)}
|
||||
>
|
||||
<span className="truncate">{g ? `#${g.numero} ${g.nome}` : "Avversario"}</span>
|
||||
<span
|
||||
className={cn(
|
||||
"shrink-0 rounded-full px-2 py-0.5 text-[13px] font-bold uppercase",
|
||||
azioniMeta[a.tipo].className,
|
||||
)}
|
||||
>
|
||||
{azioniMeta[a.tipo].short}
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="grid grid-cols-2 gap-2 px-5 pb-4 pt-4">
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in new issue
Block a user