Toglie la serie dal profilo, dalla Home e dalle notifiche di traguardo, insieme
ai badge «Risposta lampo» e «Mai un forfait» e al calcolo di serieConferme.
La colonna risposto_il e il suo trigger restano nel database, inutilizzati.
Test e documentazione allineati.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Modello: tipo sugli slot, inRosa() al posto del filtro su attivo in tutte le
letture della rosa di gioco (presenze, convocati, voti, palloni, classifiche,
badge, sollecito); gli allenatori restano solo nei compleanni e in Squadra.
- Permessi: user_roles letto una volta per tutti i ruoli; usePuoGestireEventi()
apre /eventi e il sollecito presenze anche all'allenatore, lato server con
richiediGestoreEventi(). Palloni, sondaggio e messaggi restano all'admin.
- Identità: useGiocatoreInCampo() è null per l'allenatore, così non risponde alle
presenze e non vota; useSonoAllenatore() decide cosa si vede.
- Profilo: per l'allenatore solo Docs (nome, cognome, nascita, telefono, email) e
Opzioni; card avatar e tab Opzioni estratte per riusarle.
- Home, Squadra e partita: niente statistiche personali, badge, cacche e
obiettivi per l'allenatore; in Rosa compare con la dicitura «Allenatore».
- Admin: tipo in «Aggiungi», allenatori a parte in Profili, fuori da conteggi ed
export CSI.
Test unit su rosa di gioco e completamento, route test sull'allenatore.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- schema-profili: il test pretendeva che lo slot g1 fosse libero, ma in
produzione è collegato a un giocatore vero; ora verifica che il
tentativo anonimo non cambi il valore.
- rosa: il default dei voti MVP era fuori da useMemo e faceva ricalcolare
la rosa a ogni render finché i voti non erano caricati.
- test dei badge, profili-core, push-sw, scout-stato: tipi allineati al
codice (MappaPresenze, nascita da M18, renotify, narrowing di deepEqual).
- vite.config: tipizzato come UserConfig e rimosso esbuild.keepNames,
ignorato da Vite 8 che non usa più esbuild.
- formattazione Prettier in BarraSottosezioni e classifica.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Prima veniva mostrata solo per i 17 giocatori del seed storico: chi la
inseriva da sé restava con "Invalid Date" in Squadra, perché il dato
finiva solo in profili_giocatore (privato). Un trigger ora lo sincronizza
in giocatori_squadra.nascita, colonna pubblica a tutta la rosa.
Include il backfill dei profili già compilati prima di M18 (M19),
mancante nel push iniziale.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Il sottotitolo "N partite giocate" per il criterio MVP usava totaliEventiGiocatore(),
che conta anche gli allenamenti: un numero fuorviante perché l'MVP si vota solo alle
partite del calendario interno (eventi_app), non a quelle del sito CSI. Aggiunge
contaPartiteGiocate() (presenze.ts) e Giocatore.partiteGiocate.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
I giocatori a pari valore condividono ora la stessa posizione (dense rank) invece di
essere numerati in sequenza, e il sottotitolo di ogni riga segue il criterio scelto
invece di mostrare sempre le presenze consecutive. Per Palloni mostra le volte
consecutive in cui il giocatore li ha portati (nuovo Giocatore.seriePalloni).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
rosa.ts calcolava Giocatore.palloni su completaTurni() (turni salvati + proposte
automatiche di rotazione non ancora confermate da nessuno): un giocatore poteva
avanzare nel badge senza aver mai confermato un turno, solo perché l'algoritmo lo
proponeva per un evento passato. Ora passa a conteggioTurni() solo turniSalvati
(i turni davvero confermati in turni_palloni); completaTurni() resta in uso solo
per la UI di rotazione (TurnoPalloni.tsx, PromemoriaPalloni.tsx). Corregge anche
la StatTile "quante volte hai portato i palloni" nel profilo, che leggeva lo
stesso valore.
Aggiornato palloni-badge.test.ts per verificare il nuovo comportamento (un evento
non confermato non conta più per nessuno) invece del vecchio. docs/modules/
badge.md e palloni.md aggiornati di conseguenza, spostando la voce da "Limiti
noti" a "risolto".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Il badge Pagellone si sblocca ora solo con almeno 5 pagelle ricevute
(VOTI_MINIMI_PAGELLA): un voto solo poteva sbloccarlo o farlo sparire senza
significatività statistica. Aggiunto Giocatore.votiPagella per farlo funzionare.
La migration m13 (DD-027) estende le policy RLS di M11 su pagelle_voti, mvp_voti e
badge_social_voti: votante e votato devono essere convocati all'evento (prima solo
un filtro applicativo), e per le pagelle anche pagelle_chiuse=false. Le policy
admin restano permissive di proposito. Applicata anche al progetto cloud.
Copertura test completa: unit sulla soglia minima, integration sulle nuove policy
RLS (permessi.test.ts) e un end-to-end reale (pagella-badge.test.ts) sul modello
di mvp-badge.test.ts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
EventoCard monta un hook per ogni card mostrata: usava useGiocatoreCorrente
(= useIo = useRosa, le 6 statistiche pesanti) solo per leggere il proprio id.
Il Calendario ne rende diverse insieme (prossimi eventi, compleanni, drawer del
giorno), quindi ogni apertura moltiplicava il ricalcolo dell'intera rosa.
Audit di tutti gli altri usi di useGiocatoreCorrente: 12 su 13 leggevano solo
id/nome/verita', mai una statistica. Corretti allo stesso modo (-> useGiocatoreBase):
benvenuto.tsx, VotazioneMvp, SondaggioCacche, VotoSocial, eventi.tsx,
PromemoriaPalloni (Home), TurnoPalloni, ScoutEntry, Pagelle.
partita.$id.tsx: `io` era dichiarato e mai piu' usato, rimosso.
Stesso pattern trovato anche su useRosa (non solo useGiocatoreCorrente) in
scout.tsx e RosaPresenze.tsx (montata su partita e allenamento): entrambi
passati al nuovo useAnagraficaRosa, esteso con ruolo e numero.
Unica eccezione: CelebrazioneBadge.tsx usa davvero le statistiche complete
(badge, MVP, serie) ed e' montato globalmente in __root.tsx - non downgradabile,
resta il costo di base piu' alto rimasto in giro.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
LinkProfilo (header di ogni pagina) e il Calendario (compleanni del mese) usavano
useIo/useRosa, che calcola MVP, pagelle, cacche, palloni e infortuni per l'intera
squadra tramite 6 hook e un useMemo pesante - anche se a entrambi serviva solo
id/nome/nascita/iniziali. Il Calendario in particolare pagava questo costo ad ogni
apertura solo per i compleanni del mese.
- crapp-data.ts: esporta inizialiDa, già usata internamente per il fallback avatar.
- ui-bits.tsx: LinkProfilo usa useGiocatoreBase (sola anagrafica) invece di useIo.
- rosa.ts: nuovo hook useAnagraficaRosa (id, nome, nascita) senza gli altri 5 hook
statistici ne' il useMemo su tutta la rosa.
- eventi.ts: compleanniEventi accetta solo i tre campi che usa, non l'intero
Giocatore.
- calendario.tsx: usa useAnagraficaRosa al posto di useRosa.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
conteggioTurni() contava ogni turno presente nella mappa, incluse le
assegnazioni anticipate per eventi futuri: un allenamento di lunedì con
turno già assegnato oggi (venerdì) veniva già sommato al badge "Sherpa dei
palloni" prima ancora di essersi svolto. Ora filtra su e.data < oggi, lo
stesso criterio già usato per presenze e serie — il turno resta assegnabile/
modificabile in anticipo, semplicemente non conta finché il giorno non arriva.
oggiISO() (palloni-core.ts) diventa un alias di dataOggi(): stessa correzione
di fuso della commit precedente, qui serviva anche per admin.tsx (scadenza
documenti/certificati) e cacche.ts (statistiche giornaliere), che la usano.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
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).
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>