`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>
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>
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>
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.
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>
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>
Solo whitespace: tabelle allineate, enfasi normalizzata (* -> _), a capo
coerenti. Nessuna modifica di contenuto.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>
Al primo accesso l'app collega da sola l'account Google al giocatore
la cui email registrata coincide (case-insensitive), invece di far
scegliere il nome da un elenco. Senza corrispondenza compare solo un
messaggio d'errore con un pulsante per uscire e riprovare con un altro
account: nessuna scelta manuale di ripiego.
- Migration m5: colonna `email` su giocatori_squadra, seed per Ivan
Cacciari e Davide Grilli, trigger esteso per richiedere anche il
match email oltre allo slot libero.
- slotPerEmail() sostituisce slotLiberi() (rimossa, senza più
chiamanti in produzione).
Co-Authored-By: Claude Mythos <noreply@anthropic.com>
Registra la decisione prima del codice, come chiede AGENTS.md.
Il modello dei permessi passa da "ognuno i suoi" a "ognuno i suoi, più l'admin
su tutti, tranne i file": senza, l'export per il tesseramento resta incompleto e
il lavoro amministrativo torna in chat, contro la missione del progetto. Gli
upload restano al giocatore perché su documenti d'identità e dati sanitari la
catena di responsabilità deve restare leggibile.
Aggiornati di conseguenza il documento di modulo (utenti, azioni della
dashboard, permessi) e il changelog. Annotato nel riesame che oggi non esiste
audit di chi modifica un dato.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Checklist "Fine lavoro" di AGENTS.md per il lavoro dei due commit precedenti.
- DATABASE.md: profili_giocatore creata, user_roles come fonte dei permessi, e
la nuova sezione Storage per il bucket privato.
- ARCHITECTURE.md: autenticazione e ruoli tra i punti fermi, comandi dello stack
Supabase locale; gli stessi comandi in CLAUDE.md.
- CHANGELOG.md: la voce è marcata come presente su develop e non ancora in
produzione.
- PROJECT_STATE.md: i cinque passaggi per attivare login e dashboard in
produzione, in ordine, con il redirect URI di Google e la query per il primo
admin. Segnalato che dev e produzione condividono lo stesso database.
- TODO.md: la dashboard esce dal backlog; entra il profilo lato giocatore, senza
il quale la dashboard resterebbe senza dati.
- modules/profilo-giocatore.md: registrate due scelte fatte in corso d'opera —
solo Google al posto di "Google oppure Email", e "Visualizza profilo" come
scheda in linea invece di una schermata separata.
ROADMAP.md resta con la casella non spuntata: la funzionalità è su develop, non
ancora rilasciata.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Documentation:
- Add docs/README.md, the documentation index that AGENTS.md pointed to as the
first file to read but which did not exist.
- One home per piece of information: the feature list stays in ROADMAP.md,
CHANGELOG.md records only when something shipped, TODO.md only ongoing work.
Reconcile the entries that had drifted (CSI was both done and pending;
pagelle, badge social and serie were missing from the roadmap).
- Rewrite DATABASE.md as tables: add giocatori_squadra (already created by a
migration) and profili_giocatore (planned in DD-016), fix the wrong heading
levels, drop the duplicated roadmap.
- DESIGN_DECISIONS.md: move the index to the top and sort it, extract the
template into _template-dd.md.
- ARCHITECTURE.md becomes the technical reference; CLAUDE.md no longer
duplicates it.
- Add docs/EFFICIENZA_CLOUD.md with the rules previously kept in mem/,
separating what the code enforces from the goals not yet implemented.
- Fix statements the code contradicted: mutations use setQueryData rather than
invalidateQueries, and scout_sessioni and giocatori_squadra are not read by
the code yet.
- Track the v1.0 modules with no spec in docs/modules/ from TODO.md.
AI assistants:
- AGENTS.md is the single source of the rules, now including the technical
constraints only Claude Code knew about (generated files, Vite plugins, data
access) and an end-of-work checklist that applies to every assistant.
- CLAUDE.md and .cursor/rules/crapp.mdc point to AGENTS.md instead of
restating it.
- Remove the five .cursor/*.md files, which Cursor never loaded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Campionato page showed hardcoded demo data. It now reads the real
2025/26 season (Campionato Open Misto Eccellenza, project 767, team
3359, Girone B) from the Livescore CSI Bologna portal.
The portal has no documented API: we call the same endpoints its own
pages call over ajax, so parsing must degrade gracefully. A single
server route fetches them, caches for 6 hours and serves the last good
payload on failure; the page falls back to the previous data when
nothing is available. No browser ever contacts the portal, keeping the
request count independent of how many players open the app.
Also fixes the header, which claimed "Girone C - CSI Milano".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>