Commit Graph
85 Commits
Author SHA1 Message Date
davideandClaude Opus 5 5a534547ae Riformatta i file che prettier segnalava da prima
`npm run format` ha toccato anche tre file estranei a questo lavoro:
`presenze.ts` aveva un errore prettier che `npm run lint` già segnalava, gli
altri due erano solo a capo nelle tabelle markdown. Stanno qui da soli per non
sporcare i commit di merito.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:43:02 +02:00
davideandClaude Opus 5 26bacbf700 Registra DD-021 e DD-022 e allinea la documentazione
DD-021 (molle interrompibili con motion) e DD-022 (l'app è solo chiara)
motivano le due scelte che un domani sembreranno arbitrarie: perché è entrata
una libreria di animazione dopo averne tolte 45, e perché il tema scuro è
stato cancellato invece che completato.

DD-021 riporta il numero misurato e scomodo: il bundle client cresce da 267 a
308 KB gzip. Togliere dipendenze mai importate non lo riduce, perché il
tree-shaking già le escludeva; il guadagno è sulle 50 dipendenze dirette che
diventano 21.

ARCHITECTURE e README non descrivevano più lo stack reale (Radix/shadcn) e la
sezione UI ignorava la primitiva Card e il sistema di molle. Tolto anche
`hooks/` dall'albero del progetto: la cartella non esiste più.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:55 +02:00
davideandClaude Opus 5 9b28a86f7c Aggiunge lo swipe al calendario e ripulisce le schermate
Calendario: il mese si cambiava solo con due frecce da 36 px. Ora si scorre,
e il punto d'arrivo si sceglie proiettando la velocità di rilascio invece che
dalla posizione del dito, così un colpo secco «lancia» il mese. La griglia
entra ed esce dallo stesso lato del gesto, `dragElastic` dà resistenza
progressiva al bordo al posto di uno stop netto.

Le celle con più tipi di evento generavano un gradiente a fette e ci mettevano
sopra un'ombra bianca sul numero per tenerlo leggibile: un cerotto su un
problema di contrasto. Ora fondo neutro e un puntino per tipo, con il numero
sempre su superficie piena. L'etichetta accessibile dice quanti eventi ci
sono, non solo che ce ne sono.

Profilo: le quattro switch «Notifiche convocazioni», «Promemoria allenamenti»,
«Cambi orario» e «Bacheca squadra» erano `defaultChecked` e non facevano
niente — promettevano una funzione che non esiste. Via anche la conferma
nativa prima di *cambiare* la foto: non è un'azione distruttiva, e chiedere
conferma per tutto insegna a rispondere sì senza leggere. Resta su quella che
la rimuove, che è irreversibile.

Home: la sezione «Da confermare» mostrava titolo e contenitore vuoto quando
non c'era altro da confermare, mentre tutte le altre sezioni hanno un empty
state.

Squadra: i badge in riga avevano solo `title=`, che su touch non appare mai —
aggiunto il testo per gli screen reader. I filtri per criterio erano alti
~26 px.

Più, in tutte le schermate: la primitiva `Card` al posto delle classi
ripetute, i bersagli sotto i 44 px portati in misura e il floor tipografico a
12 px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:45 +02:00
davideandClaude Opus 5 5c49294ad1 Introduce la primitiva Card e sistema tocco e accessibilità dei componenti
`rounded-3xl bg-card p-4 shadow-card` era ricopiato a mano 22 volte: cambiare
raggio od ombra voleva dire toccare venti file. `Card` in `ui-bits.tsx` è ora
l'unica definizione delle superfici, con la gerarchia dei raggi scritta invece
che implicita (contenitore 3xl, elemento interno 2xl, controllo full).

Tocco e tastiera:
- i chip presenza di `EventoCard` erano alti ~28 px ed è il controllo più
  toccato dell'app: ora `min-h-11`, con 8 px di spazio fra l'uno e l'altro;
- stessa cura per il link «Apri partita», la chiusura di `CelebrazioneBadge` e
  il titolo di `SezioneTendina`;
- `aria-pressed` sui controlli a stato, `aria-controls` sulle tendine (che
  avevano `aria-expanded` senza il pannello a cui si riferisce), `aria-busy`
  sui caricamenti;
- `BottomNav`: lo stato attivo era comunicato solo dal colore. Ora cambia
  anche il peso del testo, compare una barretta sopra l'icona e c'è
  `aria-current="page"`. La voce «Home» diventa «Oggi», che dice cosa
  contiene. La barra è un materiale traslucido con bordo sfumato al posto
  della riga netta.
- `Barra` espone `role="progressbar"` con i valori.

Il testo sotto i 12 px è sparito (108 occorrenze fra `text-[9px]`,
`text-[10px]` e `text-[11px]`): sotto quella soglia la leggibilità cala e su
iOS non scala con Dynamic Type. La gerarchia la fanno peso e maiuscolo.

`Avatar` aveva `alt="Foto di 12"` quando il fallback è il numero di maglia —
non descrive niente e il nome è già scritto accanto, quindi alt vuoto. Aggiunti
`width`/`height` per non far saltare il layout al caricamento.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:24 +02:00
davideandClaude Opus 5 1ff650ecd5 Aggiunge i test della proiezione del momento
`proietta()` decide dove atterra uno swipe, quindi è la funzione che rompe il
gesto se sbaglia: il test copre segno, simmetria, linearità nella velocità e
il valore atteso della decelerazione esponenziale (1000 px/s -> ~499 px).
Copre anche i preset di `molla`, per evitare che un rimbalzo finisca per
sbaglio sul default o che una durata esca dalla scala utile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:11 +02:00
davideandClaude Opus 5 e7863ab950 Passa le animazioni a molle interrompibili
Il movimento era fatto con `@keyframes` e transizioni a durata fissa: nessuna
di quelle animazioni può essere afferrata a metà. Se l'utente scorre o tocca
mentre una è in corso, quella va avanti per conto suo e per ripartire deve
prima finire.

`lib/molla.ts` raccoglie i parametri, che sono i due di Apple in «Designing
Fluid Interfaces» — rimbalzo e durata, non massa/rigidità/smorzamento.
`molla.ui` (nessun sorpasso) è il default; `molla.slancio` si usa solo dopo un
gesto che portava già inerzia. `proietta()` calcola dove finirebbe un elemento
lanciato, con la stessa decelerazione esponenziale dello scroll iOS.

Nei tre componenti:
- `Reveal` compare quando entra davvero nel viewport. Prima partiva al mount,
  quindi gli elementi sotto la piega consumavano l'animazione a vuoto e
  l'utente li trovava già fermi. Il ritardo massimo scende da 480 a 200 ms.
- `Barra` anima `scaleX` invece di `width`: la larghezza rifà il layout a ogni
  frame, la trasformazione la gestisce il compositore.
- `Numero` usa una molla al posto dell'interpolazione a durata fissa: se il
  dato cambia a metà conteggio il numero cambia rotta da dov'è invece di
  ripartire da capo. Sparisce la prop `durata`, che nessuno passava.

`lib/motion.ts` resta solo per il rilevamento del movimento ridotto (che qui
guarda anche `deviceMemory`, cosa che `useReducedMotion` non fa) e per i
coriandoli.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:01 +02:00
davideandClaude Opus 5 18c6205e06 Rimuove 43 componenti shadcn inutilizzati e installa motion
Dei 45 componenti in `src/components/ui/` solo `drawer` e `sonner` erano
importati da qualche parte. Gli altri 43 — e con loro ~45 dipendenze: tutti i
`@radix-ui/*`, recharts, react-hook-form, date-fns, embla, cmdk, input-otp,
react-day-picker, react-resizable-panels, class-variance-authority,
tw-animate-css — erano superficie di aggiornamento e di sicurezza pagata a
vuoto. Stessa sorte per `src/hooks/use-mobile.tsx`, mai importato. `zod`
resta: lo usano tre route API.

Le dipendenze dirette passano da 50 a 21. Il bundle client NON cala per
questo: quel codice non era importato e il tree-shaking già lo escludeva.

Nella direzione opposta entra `motion`, l'unica aggiunta: serve per le molle
interrompibili che nessuna `@keyframes` CSS può dare (vedi DD-021). Costa ~42
KB gzip, che le rimozioni non compensano — il bundle client passa da 267 a
308 KB gzip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:41:49 +02:00
davideandClaude Opus 5 230ea1d156 Sistema i meta della PWA e traduce le schermate di sistema
`viewport-fit=cover` mancava, quindi `env(safe-area-inset-bottom)` valeva
sempre 0: il codice safe-area della BottomNav c'era già ma era inerte, e su
iPhone in standalone la barra finiva sotto la home bar.

`theme-color` e `background_color` erano `#111111` su un'app con fondo quasi
bianco: barra di stato nera e splash nero prima di una UI chiara.

`lang="en"` su un'app interamente in italiano: gli screen reader leggevano
tutto con fonetica inglese. Con esso 404 e schermata d'errore, che erano
rimaste in inglese.

L'anteprima social puntava a un'immagine di preview Lovable su R2 ormai
scaduta e dichiarava `twitter:site @Lovable`: ora usa l'icona della squadra,
con `summary` al posto di `summary_large_image` visto che l'unica immagine
disponibile è quadrata.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:41:36 +02:00
davideandClaude Opus 5 38e0185325 Corregge i contrasti della palette e toglie il tema scuro
I colori di stato non passavano WCAG AA con il testo bianco sopra: success
3.39:1, training 3.49:1, info ~3.7:1 (chip «Presente», «Allenamento», celle
del calendario). Le luminosità sono abbassate fino a superare 4.5:1.

I gradi dei badge erano il caso peggiore: `text-oro` su bianco sta a 1.9:1 e
`text-argento` a 2.5:1, cioè illeggibili. Nascono i token `--oro-testo`,
`--argento-testo` e `--bronzo-testo` per il testo, mentre le varianti chiare
restano dove servono davvero, su sfondi e bordi.

Il blocco `.dark` non veniva mai applicato — nessun interruttore, nessun
`prefers-color-scheme` — ed era anche incoerente: l'accento diventava
grigio-blu e mancavano success, warning, info, training, i metalli, i due
gradienti e le due ombre. Un tema mai attivato non si accorge di rompersi,
quindi via, con `color-scheme: light` dichiarato esplicitamente.

Nello stesso file:
- `:focus-visible` globale, prima non c'era nessuna regola di focus;
- tracking del display specifico per taglia (`font-display-sm/lg`): un solo
  valore per tutte le dimensioni è sbagliato da qualche parte;
- utility `materiale` e `bordo-sfumato` per la chrome traslucida, con
  `prefers-reduced-transparency` e `prefers-contrast`;
- movimento ridotto: dissolvenza breve invece dell'azzeramento di ogni
  transizione, così resta un feedback che spiega cosa è cambiato;
- rimossi i token di chart e sidebar (i componenti che li usavano non ci sono
  più) e l'import di tw-animate-css, che non era usato da nessuna classe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:41:25 +02:00
davideandClaude Sonnet 5 7433391c30 Aggiunge la skill apple-design per il lavoro sull'interfaccia
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 12:02:30 +02:00
davideandClaude Opus 5 822180bffc Riscrive AGENTS.md e riallinea la documentazione allo stato reale.
I riferimenti ai documenti in AGENTS.md erano rotti: una venticinquina di link
nella forma docs/[README.md](http://README.md), che spezzavano il nome del file
a meta e puntavano a domini inesistenti. Ora sono percorsi relativi verificati,
con CHANGELOG.md e DESIGN_DECISIONS.md sotto docs/ e PROJECT_STATE.md in root.

Tolte da AGENTS.md le sezioni Architettura, Documentazione e Struttura della
documentazione: duplicavano ARCHITECTURE.md e docs/README.md con uno stack ormai
parziale, contro la regola "ogni informazione ha una sola casa" che docs/README.md
stesso impone. Aggiunti invece i comandi, bun e la guardia minimumReleaseAge:
Codex e Cursor leggono solo AGENTS.md e non avevano modo di sapere come si
verifica una modifica. Scritta la checklist "Fine lavoro" che CLAUDE.md citava
senza che esistesse.

Nuova regola: chi aggiunge o modifica una funzione scrive o aggiorna il test nello
stesso lavoro, i test devono essere verdi e la doc del modulo va aggiornata se il
comportamento cambia (DD-020). Serve perche con main come branch di lavoro non
c'e piu un ambiente di prova tra il codice e i giocatori.

Il flusso git documentato non descriveva piu la realta: main e arrivato a 43
commit di vantaggio su develop, rimasto fermo. DD-003 e ora sostituita da DD-019:
il branch dei commit lo decide l'utente, l'assistente al massimo consiglia un
branch dedicato e non committa, non pusha e non apre PR di propria iniziativa.

Allineati di conseguenza ARCHITECTURE.md (sezione branch), README.md (flusso,
install con bun, comandi di test e lint), ROADMAP.md e TODO.md (le voci spuntate
sono in produzione, non su develop) e PROJECT_STATE.md (auth e profilo giocatore
in produzione, 20 migration fino a M9, passaggi 1-3 e 5 fatti).

Corretti poi sei disallineamenti tra documentazione e codice, ognuno verificato
sul sorgente:

- badge.md e obiettivi-squadra.md dicevano che le serie sono inerti e che
  serieAllenamenti e sempre 0, quindi badge e obiettivo "Continuita di squadra"
  non sbloccabili. Falso da 7237e8f: presenze.ts:48 le calcola e rosa.ts:64-67 le
  attacca al Giocatore. Il limite che resta e un altro, ora scritto: risposto_il
  non e ricostruibile prima di m9, quindi sulle risposte vecchie serieConferme e
  un'approssimazione.
- TODO.md e PROJECT_STATE.md davano il tracciamento tesseramento CSI come da
  fare, mentre ROADMAP, CHANGELOG e DATABASE lo davano per fatto. Lo e:
  admin.tsx:264-278 registra numero e data, :472 mostra Tesserato/Da tesserare,
  :676 il contatore.
- collegamento-csi.md indicava il check di parsing in src/lib/csi-core.test.ts;
  sta in test/unit/csi-core.test.ts, in src/lib non esiste nessun .test.ts.
- profilo-giocatore.md annunciava cinque aree del profilo e ne elencava sette.
- "Segnala un bug" e "Suggerisci una nuova funzionalita" (profilo.tsx:259-276,
  commit 72a9864) non erano documentati da nessuna parte, contro DD-002: ora
  stanno in profilo-giocatore.md e nel CHANGELOG.

npm run test: 28/28 file ok. npm run lint: 12 problemi, identici a prima di
questa modifica e tutti in src/, non toccato qui.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:24:22 +02:00
davideandClaude Opus 5 7237e8ff39 Calcola davvero le serie di presenze e sblocca badge e obiettivo.
I tre contatori (serieAllenamenti, seriePartite, serieConferme) e streak erano
zero fisso in useRosa(): la sezione Serie di presenze del profilo mostrava sempre
progresso nullo, i badge legati alla costanza erano impossibili da sbloccare e
l'obiettivo Continuita di squadra restava a 0/12.

serieConsecutiva() e serieConferme() (src/lib/presenze.ts) derivano le serie dagli
eventi passati e da risposte_presenze gia in cache, senza query aggiuntive.

Migration m9: nuova colonna risposto_il con l'istante della prima risposta, resa
immutabile da un trigger, confrontata con eventi_app.creato_il per le conferme
entro 24 ore. Serviva perche aggiornato_il registra l'ultima modifica, quindi chi
rispondeva subito e cambiava idea dopo risultava lento.

Corregge anche la barra di progresso, che misurava valore/prossimo e tornava
indietro a ogni traguardo raggiunto (2/3 = 67%, poi 3/6 = 50%).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:46:04 +02:00
Ivan CacciariandCursor 952f7b43d3 Sposta Completa il tuo profilo sopra Prossimo impegno in home.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 12:50:43 +02:00
Ivan CacciariandCursor 438076c572 Rende collassabili badge e tesseramento nel profilo e toglie Scout Live dalla home.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 12:43:53 +02:00
Ivan CacciariandCursor fe1ac5434c Alleggerisce Squadra e Classifica con sezioni a tendina e limita i prossimi eventi a 4.
Rimuove anche Scout Live dalle statistiche di squadra per snellire la schermata.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 12:01:13 +02:00
Ivan CacciariandCursor 9aef361bf0 Sposta lo storico match in Classifica e rimuove i risultati ufficiali duplicati.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 11:40:03 +02:00
davide f70430e1bf Retro-documenta i moduli v1.0 mancanti in docs/modules/
Presenze, Serie di presenze, Scout Live, Pagelle, MVP, Badge, Palloni,
Obiettivi di squadra, Infortuni, Notifiche: chiudono il debito di
documentazione tracciato in TODO.md (DD-002). Le sei route API
pubbliche vengono descritte dentro il modulo a cui appartengono.
2026-09-03 15:10:18 +02:00
davide 72a9864e94 Aggiunge segnalazione bug e richiesta funzionalità dal profilo
I template GitHub guidano chi apre una issue a fornire titolo,
descrizione strutturata ed eventuali screenshot invece di un campo
libero. Dal profilo, prima di "Esci", due link aprono direttamente
il template giusto su GitHub.
2026-09-03 14:46:38 +02:00
davide 2db2086c10 Aggiunge licenza 2026-09-03 14:23:56 +02:00
davide ac4a4a96e8 Blocca il salvataggio se il numero di maglia è già assegnato
Prima era solo un warning e il salvataggio procedeva comunque,
generando doppioni non voluti in rosa.
2026-09-03 14:22:11 +02:00
davide 6286c18a72 Sostituisce l'input libero del ruolo con un menu a tendina
Evita ruoli scritti in modo incoerente (maiuscole, refusi) sia in
modifica che in aggiunta giocatore.
2026-09-03 14:17:30 +02:00
davideandClaude Sonnet 5 70b4123452 Forza la revalidazione dell'avatar dopo la sostituzione della foto
Con cacheControl: "60" l'immagine sostituita poteva restare quella
vecchia per un minuto se la CDN davanti allo storage non varia la
cache in base alla query string di cache-busting (?v=).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 14:05:50 +02:00
davideandClaude Sonnet 5 0c2a6c5330 Chiede conferma prima di cambiare o rimuovere la foto profilo
Entrambe le azioni avvenivano subito, senza possibilità di annullare
per errore.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 13:58:32 +02:00
davideandClaude Sonnet 5 5c9ffb84e8 Filtri classifica giocatori tutti su una riga senza scroll
Rinomina "Cacche/partita" in "Cacche" e passa i pill da flex-wrap a
flex-nowrap con flex-1/truncate, così entrano tutti su una riga sola
senza andare a capo né richiedere swipe orizzontale.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 13:41:16 +02:00
davideandClaude Sonnet 5 988eb6d575 Evita lo scroll orizzontale nei filtri della classifica giocatori
I pill (Presenze, Media voto, MVP, Palloni, Cacche/partita) andavano su
una riga scrollabile orizzontalmente; ora vanno a capo con flex-wrap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 13:36:52 +02:00
davideandClaude Sonnet 5 0710d143a9 Documenta l'applicazione della migration M4 in produzione
Il gate "M4 non applicabile finché la squadra non è collegata" è superato:
il login era già l'unica via d'accesso lato app, quindi i giocatori non
ancora collegati non erano comunque impattati dal residuo di accesso anon
che M4 chiudeva. Aggiorna anche DD-018, ormai stale: l'email dei giocatori
si imposta da /admin, non solo via migration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 13:28:23 +02:00
davideandClaude Sonnet 5 9c173df753 Corregge riferimenti alla migration M3, mai applicata
M3 esisteva solo come bozza archiviata in docs/archive/migrations/: il bucket
profili-giocatore è creato dalla migration M2 insieme alla tabella. Allinea
PROJECT_STATE.md (12 -> 18 migration), DATABASE.md, CHANGELOG.md, TODO.md,
DESIGN_DECISIONS.md, test/README.md e il test di integrazione dei profili.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:00:27 +02:00
davideandClaude Mythos a07c8104d5 Aggiorna docs/modules/collegamento-csi.md: fallback non è più sui dati demo
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>
2026-09-03 10:40:03 +02:00
davide 224bb93beb Chiude DD-015: la rosa non è più hardcoded
Aggiorna DESIGN_DECISIONS.md (DD-015 da "In valutazione" ad "Accettata",
con le conseguenze reali: fallback nascita e crapp-data.ts come solo
seed/fallback), DATABASE.md, ARCHITECTURE.md e PROJECT_STATE.md di
conseguenza.
2026-09-03 10:17:13 +02:00
davide 923d1fe762 Aggiorna i test per le nuove firme con rosa esplicita
completaTurni() e csvScoutMatch() prendono ora la rosa come parametro
invece di leggerla dalla lista statica di crapp-data.ts.
2026-09-03 10:17:07 +02:00
davide 4c0ea66126 Aggancia Squadra, Presenze, Pagelle, Scout e calendario alla rosa reale
convocatiEvento() e compleanniEventi() prendono ora la rosa come parametro
invece di leggere la lista statica; csvScoutMatch() idem. Le schermate di
gestione eventi, dettaglio allenamento/partita, calendario e scout live,
più i widget di presenze/pagelle/voto MVP/voto social/sondaggio
cacche/turno palloni, passano tutte la rosa letta da useRosa() o
useGiocatoriSquadra(): un giocatore aggiunto o disattivato dalla dashboard
admin ora si riflette ovunque.
2026-09-03 10:17:03 +02:00
davide b6c0f40f66 Aggancia funzioni di libreria e route push alla rosa reale
obiettivi.ts, palloni-core.ts, presenze-mese.ts e user-store.ts non
dipendono più dalla lista statica di crapp-data.ts ma ricevono/leggono la
rosa reale (percentuali obiettivo, rotazione turno palloni, riepilogo
presenze mensile, identità del dispositivo). Le route API per le notifiche
push (push-messaggio, promemoria-palloni, sollecita-presenze) leggono la
squadra lato server con leggiGiocatoriSquadra(), filtrando attivo.
2026-09-03 10:16:52 +02:00
davide 7e93229eee Sposta QueryClientProvider sopra AppShell per evitare crash SSR
useGiocatoreBase() ora interroga giocatori_squadra con useQuery, ma
RootComponent la chiamava prima di montare QueryClientProvider: ogni pagina
falliva in SSR con "No QueryClient set". Il provider avvolge ora tutto fin
dall'inizio; la logica di redirect/loading si sposta in un componente
AppShell interno, comportamento invariato.
2026-09-03 10:16:40 +02:00
davide 4470139504 Aggancia useRosa() a giocatori_squadra (DD-015)
useRosa()/useIo()/useObiettivi() leggono ora l'anagrafica da giocatori_squadra
tramite useGiocatoriSquadra(), filtrando solo i giocatori attivo. crapp-data.ts
resta il seed storico e il fallback (rosaFallback) e fornisce anche la data di
nascita per id, non ancora una colonna della tabella. Aggiunge
giocatori-squadra.server.ts per leggere la rosa lato route API (stesso pattern
di eventi.server.ts).
2026-09-03 10:16:35 +02:00
davideandClaude Sonnet 5 cce6525f09 Rimuove la dicitura DEVELOP dalla schermata di benvenuto
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 15:33:27 +02:00
davideandClaude Sonnet 5 c7445cfab1 Aggiunge il tracciamento del tesseramento CSI in giocatori_squadra
Numero e data della tessera arrivano dal comitato dopo l'iscrizione, quindi
li scrive solo un admin (come numero/ruolo): estende il trigger di M1/M5,
aggiunge il pannello dedicato in /admin con badge e conteggio in dashboard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 15:27:12 +02:00
davideandClaude Sonnet 5 ff45b2379c Aggiunge unit test per i moduli lib rimasti scoperti
Copre la logica pura isolabile di avatar-store, error-capture, error-page,
lovable-error-reporting, profili (validazione upload), push-client (guardie
senza DOM), scout-stato e webpush.server (firma JWT VAPID con chiavi P-256
generate al volo, fetch intercettato). Alza i file di src/lib coperti da 19
a 28 su 37, senza introdurre nuove dipendenze.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 11:34:09 +02:00
davide d3b117e470 Ordina la rosa e la squadra per cognome
Sposta dividiNome in crapp-data.ts per riordinare la rosa di fallback per
cognome; la query a giocatori_squadra ora ordina per cognome, nome invece
che per id.
2026-09-02 10:59:28 +02:00
davide 64771fffc6 Chiude l'accesso anonimo a scout_partite in M7
Il REVOKE per scout_partite andava messo qui, dove la tabella viene creata,
non in M4. Allinea l'accesso anonimo alle altre tabelle post-M4.
2026-09-02 10:59:20 +02:00
davide 395cee3c9c Rimuove REVOKE su scout_partite da M4 (tabella non ancora esistente)
La tabella scout_partite viene creata solo in M7 (2026-09-01): il REVOKE in
questa migration del 2026-08-31 precedeva la sua creazione.
2026-09-02 10:59:16 +02:00
davideandClaude Sonnet 5 5e4ad307c9 Aggiorna CHANGELOG e PROJECT_STATE con M6 e M7
docs/CHANGELOG.md e PROJECT_STATE.md erano fermi al 30/08 e non riportavano
gli ultimi due commit: foto profilo su Supabase Storage (M6) e
sincronizzazione dello Scout Live tra dispositivi (M7).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 09:43:22 +02:00
Ivan CacciariandCursor c52e4c4e27 Separate player presence from scout stats
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:42:35 +02:00
Ivan CacciariandCursor d63beae04c Replace demo stats with real data
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:34:07 +02:00
davideandClaude Sonnet 5 c314a08f6d Sincronizza lo Scout Live tra dispositivi (blocco e archivio partite)
Due bug architetturali, entrambi con la stessa causa: dati che vivevano
solo in localStorage, quindi visibili a un solo dispositivo.

- Il blocco "chi sta scoutando" (scout-live.ts) non funzionava mai tra
  telefoni diversi: due persone potevano prendere il controllo insieme
  da dispositivi diversi, sovrascrivendosi a vicenda le azioni nel
  salvataggio condiviso. Ora usa scout_sessioni, tabella già presente
  nello schema ma mai collegata al codice.

- La partita scoutata finita (scout-store.ts) veniva salvata solo in
  localStorage: "Punti/Ace/Muri squadra" e le presenze derivate dallo
  scout esistevano solo sul telefono di chi aveva chiuso la partita.
  Nuova tabella scout_partite archivia la partita completa (azioni
  incluse) per tutta la squadra.

useScoutMatches() mantiene la stessa firma di prima (ScoutMatch[]), ora
alimentata da una query invece che da localStorage: nessuna modifica
necessaria nei punti che la leggono (squadra, classifica, home,
dettaglio partita, rosa). Rigenerati i tipi Supabase.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 16:08:59 +02:00
davideandClaude Sonnet 5 d2d62b6799 Sincronizza le foto profilo dei giocatori su Supabase Storage
Le foto caricate in Profilo vivevano solo in localStorage: ogni giocatore
vedeva la propria foto solo sul proprio dispositivo, mai quella dei
compagni nella rosa (Squadra). Ora vengono caricate in un bucket
pubblico dedicato (avatar-giocatori, migration m6) e il componente
Avatar carica l'URL pubblico con fallback su numero/iniziali se assente
o non ancora caricata.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 14:32:19 +02:00
davideandClaude Sonnet 5 f6036f21ec Rende raggiungibile il voto MVP dalle card dei risultati
"Ultima partita" in home e le card di "Storico match" in squadra ora
sono link a /partita/$id quando esiste un evento di calendario con la
stessa data del risultato (CSI o scout), con un'indicazione "Vota MVP"
quando non è ancora stato eletto. Prima erano card statiche: per votare
bisognava trovare la partita a mano dal calendario.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 13:56:56 +02:00
davideandClaude Sonnet 5 1a93c7657a Aggiorna i test dopo la rimozione della classifica e dello storico dummy
Tolti i check su `classifica`, `classificaConScout` e `storicoMatch`,
non più esportati da crapp-data.ts / scout-store.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 13:39:12 +02:00
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
davideandClaude Sonnet 5 0a04025fe9 Rimuove i dati dummy della classifica e usa i risultati CSI reali
La classifica e lo storico partite mostravano dati inventati (squadre e
risultati finti) come base, poi sovrascritti dai dati CSI quando
disponibili. Ora classifica, ultimi risultati, storico match e obiettivi
di squadra legati alle vittorie usano solo dati reali (CSI o scout live),
con stati vuoti quando i dati CSI non sono ancora disponibili.

Include anche la correzione di tutti gli errori di formattazione
prettier segnalati da `npm run lint` sul resto del codice sorgente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 13:38:33 +02:00
davideandClaude Sonnet 5 d813dee282 Dashboard admin: aggiungi, disattiva e riattiva giocatori
- Aggiungi giocatore: nuovo form in /admin (nome, cognome, numero,
  ruolo, email opzionale), id g<N> calcolato in automatico.
- Email modificabile anche per i giocatori già in rosa dal pannello
  Dati squadra, non solo alla creazione — completa quanto rimandato
  da DD-018.
- Disattiva/Riattiva: un giocatore che lascia la squadra sparisce
  dalla rosa attiva senza che la riga venga eliminata, così presenze,
  voti, pagelle e badge della stagione restano agganciati al suo id.
  Nuova sezione "Giocatori disattivati" per riattivarli.
- Messaggio d'errore leggibile per l'unico vincolo unique della
  tabella (email duplicata) invece del codice Postgres grezzo.

Nessuna migration: sia l'inserimento sia la modifica passano dalla
policy admin FOR ALL già esistente su giocatori_squadra.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 11:29:41 +02:00