Files
CRAPP/docs/modules/profilo-giocatore.md
T
davideandClaude Sonnet 5.5 de78431090 Toglie la foto tessera dal profilo (DD-044)
Il Profilo non chiede più la foto tessera e la scheda admin non la mostra.
Il completamento diventa dati personali 34%, documento 33%, certificato 33%.
La migration m29 elimina la colonna profili_giocatore.foto_path; le 4 foto
già caricate sono state cancellate dal bucket profili-giocatore. Migration
applicata in produzione.

Test: pesi e sezioni di profili-core, rendering di CampiProfilo, colonna
rimossa sul database locale. Documentati DD-044, modulo profilo-giocatore,
DATABASE, ROADMAP e changelog.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 15:03:04 +02:00

18 KiB
Raw Blame History

Modulo — Profilo Giocatore

Stato: implementato File principali: src/lib/profili.ts, src/lib/profili-core.ts, src/routes/profilo.tsx, src/routes/admin.tsx


Obiettivo

Il modulo "Profilo Giocatore" raccoglie tutte le informazioni personali, amministrative e documentali di ciascun membro della squadra.

L'obiettivo è centralizzare in un'unica schermata tutti i dati necessari sia al giocatore sia agli amministratori, eliminando la gestione tramite chat, documenti cartacei e fogli Excel.

Utenti

L'allenatore ha un profilo ridotto (solo Docs con i dati personali essenziali e Opzioni): la specifica sta in allenatore.md.

Giocatore

Può:

  • visualizzare il proprio profilo
  • modificare i propri dati personali
  • aggiornare il certificato medico
  • aggiornare i documenti
  • caricare le immagini richieste

Amministratore

Può:

  • visualizzare il profilo di tutti i giocatori
  • scaricare documenti e certificati
  • esportare i dati necessari al tesseramento CSI
  • verificare lo stato di completamento dei profili
  • modificare i dati squadra di qualsiasi giocatore (nome, cognome, numero, ruolo, email)
  • compilare e correggere i dati personali e del documento al posto di un giocatore (DD-017)
  • scollegare un account da un profilo, liberando lo slot
  • aggiungere un nuovo giocatore alla rosa (id, nome, cognome, numero, ruolo, email opzionale), oppure un allenatore (tipo «Allenatore»: niente numero né ruolo, DD-034)
  • disattivare un giocatore che ha lasciato la squadra, e riattivarlo in caso di errore: la riga non viene eliminata, così presenze, voti, pagelle e badge della stagione restano agganciati al suo id

Non può caricare o sostituire i file altrui: documento e certificato restano responsabilità del giocatore che li fornisce.

Flusso utente

Primo accesso

  1. Login tramite Google oppure Email. Implementato con il solo Google: la squadra ha tutti un account Google, e un secondo metodo è additivo (un bottone in più sulla stessa schermata) il giorno che serve.
  2. Collegamento automatico al proprio giocatore, confrontando l'email dell'account Google con l'email registrata in giocatori_squadra (DD-018). Nessuna scelta manuale: se l'email non corrisponde a nessun profilo, l'accesso si ferma con un messaggio che invita a contattare un amministratore.
  3. Accesso alla Home.

Se il profilo non è completo compare automaticamente un widget di completamento.

Home

Il giocatore visualizza un widget dedicato e, quando serve, l'avviso sul certificato medico.

Completa il tuo profilo

Viene mostrata una barra di avanzamento (esempio: Profilo completato — 85%), composta dalle seguenti sezioni.

  • Dati personali
  • Documento di identità
  • Certificato medico

Quando tutte le sezioni sono complete il widget scompare automaticamente.

Il tap apre Profilo sulla sottosezione Documenti (/profilo?tab=documenti), non sulla tab Stagione.

Avviso certificati

Stato: implementato (DD-035, soglia del giocatore DD-041).

Un avviso in Home segnala i certificati medici in scadenza o scaduti, così nessuno se ne accorge quando il giocatore è già fuori regola. Si calcola al volo dalla data di scadenza già salvata: niente tabella, niente migration, niente push.

Chi lo vede

Utente Cosa vede Al tocco
Admin l'avviso dello staff: i nomi di tutti i giocatori coinvolti niente, non è cliccabile
Giocatore interessato l'avviso personale: solo il proprio certificato apre /profilo?tab=documenti
Admin che è anche giocatore entrambi: lo staff (senza il suo nome) e il proprio personale, a 30 giorni personale: apre /profilo?tab=documenti
Altri giocatori niente —
Allenatore niente: non vede i certificati altrui e non ne ha uno (DD-034) —

L'avviso dello staff non è cliccabile, come quello dei palloni: l'admin non può caricare il certificato al posto del giocatore (DD-017), quindi può solo sollecitarlo, e il giocatore riceve già il proprio avviso. Quello personale porta invece dove si carica il certificato nuovo, come il widget «Completa il tuo profilo».

I certificati sono dati sanitari: fuori da /admin li legge solo il titolare (DD-016). Nessuna policy cambia, perché useProfili() restituisce già tutti i profili a un admin e il solo proprio a un giocatore.

Quando compare

giorni è la differenza in giorni di calendario tra la scadenza e oggi (ora locale). La soglia del giallo dipende da chi guarda (DD-041): il giocatore è avvisato un mese prima dello staff.

Chi guarda Soglia
Giocatore GIORNI_AVVISO_CERTIFICATO_GIOCATORE = 30
Admin GIORNI_AVVISO_CERTIFICATO = 7
Condizione Stato Avviso
giorni > soglia valido nessuno
0 ≤ giorni ≤ soglia in scadenza giallo (warning)
giorni < 0 scaduto nero (primary)
data o file mancanti mancante nessuno

Esempio: scadenza il 5 ottobre 2026. Dal 5 settembre l'avviso giallo compare solo al giocatore; dal 28 settembre anche agli admin; dal 6 ottobre è nero per entrambi.

  • Il giorno della scadenza il certificato vale ancora, coerente con statoScadenza(): il giocatore compare nel giallo con «scade oggi» e passa al nero dal giorno dopo.
  • L'avviso nero resta finché il giocatore non aggiorna la data: non c'è un limite di tempo.
  • Il certificato mancante non genera avviso: è un problema diverso, già visibile nella tab Profili di /admin e nel widget di completamento del giocatore.
  • Sono esclusi i giocatori disattivati e gli allenatori: conta solo la rosa (inRosa(), cioè attivo e tipo = 'giocatore').

Testi

Avviso Titolo (staff / personale) Riga
Giallo, staff «Certificati in scadenza» «Mario Rossi — scade tra 5 giorni», «… — scade domani», «… — scade oggi»
Nero, staff «Certificati scaduti» «Mario Rossi — scaduto il 12/09/2026»
Giallo, personale «Certificato in scadenza» «Il tuo certificato medico scade tra 5 giorni» / «domani» / «oggi»
Nero, personale «Certificato scaduto» «Il tuo certificato medico è scaduto il 12/09/2026: caricane uno nuovo»

Il numero di giorni scende da solo ogni giorno (30… 7, 6, 5… domani, oggi): l'avviso non conserva niente, rilegge la data a ogni apertura della Home.

Più giocatori

  • Più giocatori nello stesso stato stanno in un unico avviso, una riga ciascuno, e compaiono tutti: nessun limite al numero di nomi, anche a inizio stagione quando ne scadono molti insieme.
  • Se ci sono sia certificati in scadenza sia scaduti compaiono due avvisi: prima quello nero, poi quello giallo.
  • Ordine delle righe: dalla scadenza più vicina nel giallo, dal certificato scaduto da più tempo nel nero; a parità di data, alfabetico per cognome e poi per nome. L'ordine è stabile, quindi l'elenco non si rimescola tra un'apertura e l'altra.

Aspetto e posizione

  • Stessa forma del banner palloni (PromemoriaPalloni): card arrotondata a tutta larghezza con icona e titolo in font-display maiuscolo, righe in testo piccolo sotto.
  • Giallo: sfondo bg-warning, testo text-warning-foreground. Nero: sfondo bg-primary, testo text-primary-foreground. L'app è solo chiara (DD-022), quindi il nero non rischia di confondersi con lo sfondo.
  • In Home sta subito sotto il banner palloni e sopra «Completa il tuo profilo»: prima ciò che scade oggi, poi ciò che manca.

Rinnovo

Il giocatore rinnova dal proprio profilo, sottosezione Documenti: carica il file nuovo e aggiorna la data. Il salvataggio aggiorna la cache dei profili (setQueryData), quindi il suo avviso personale sparisce subito. Nell'avviso dello staff il nome sparisce alla lettura successiva dei profili da parte dell'admin (cache di 30 minuti, useProfili()), senza nessuna azione da parte sua. Quando non resta nessuno, l'avviso non compare più.

Basta aggiornare la data: l'avviso guarda solo quella (e la presenza di un file). Che il file caricato sia davvero quello nuovo resta un controllo dell'admin, come oggi. Anche l'admin può correggere la data dalla scheda del giocatore (DD-017, non il file): l'avviso segue la data, chiunque l'abbia scritta.

Caricamento

Finché ruoli e profili non sono arrivati, l'avviso non compare: così un admin che è anche giocatore non vede per un attimo l'avviso personale prima di quello dello staff. Se la lettura dei profili fallisce l'avviso semplicemente non compare, senza messaggio d'errore: la Home non deve rompersi per un dato accessorio.

Implementazione

Pezzo Ruolo
GIORNI_AVVISO_CERTIFICATO (profili-core.ts) la soglia dello staff, 7
GIORNI_AVVISO_CERTIFICATO_GIOCATORE la soglia del giocatore, 30 (DD-041)
giorniAllaScadenza(scadenza, oggi) differenza in giorni di calendario tra due date AAAA-MM-GG, negativa se scaduto
avvisiCertificati(rosa, profili, oggi, soglia) funzione pura (soglia di default 7): restituisce { scaduti, inScadenza }, ognuno una lista ordinata di { giocatoreId, nome, cognome, scadenza, giorni }
avvisiCertificatiUtente(rosa, profili, oggi, utente) funzione pura: { personale, staff } per chi guarda; l'admin giocatore ha entrambi, senza il suo nome nello staff (DD-041)
testoScadenza(giorni) «scade oggi» / «scade domani» / «scade tra N giorni»
src/components/crapp/AvvisoCertificati.tsx legge useGiocatoriSquadra(), useProfili(), useIsAdmin() e l'utente corrente; sceglie avviso dello staff o personale e disegna le card
src/routes/index.tsx monta <AvvisoCertificati /> subito dopo <PromemoriaPalloni />
  • "Oggi" viene da oggiISO() (palloni-core.ts), in ora locale. Non da new Date().toISOString(), che è in UTC e tra mezzanotte e le 2 darebbe il giorno prima.
  • Nessuna query nuova: useProfili() ha la stessa chiave di cache usata da Profilo e /admin, quindi al massimo una lettura di profili_giocatore per sessione (vedi EFFICIENZA_CLOUD.md). Per l'allenatore il componente non legge i profili.
  • Test in test/unit/profili-core.test.ts: avvisi per utente (admin giocatore, admin puro, giocatore semplice), soglia dello staff (8 giorni no, 7 sì, 0 sì, −1 scaduto) e del giocatore (31 no, 30 sì), certificato senza file o senza data escluso, giocatore disattivato e allenatore esclusi, ordinamento (per data, poi alfabetico), testi al singolare e al plurale, cambio di mese e di anno nel calcolo dei giorni.

Profilo

Il profilo viene suddiviso in sette aree.

Dati Giocatore

Dati squadra — solo lettura, gestiti esclusivamente dagli amministratori.

  • Nome
  • Cognome
  • Numero di maglia
  • Ruolo

Dati personali — modificabili dal giocatore.

  • Data di nascita — oltre a profili_giocatore.data_nascita, un trigger la sincronizza in giocatori_squadra.nascita (DD-031): a differenza degli altri campi di questa sezione, visibile a tutta la squadra, non solo al giocatore stesso o all'admin (alimenta Squadra e i compleanni nel Calendario, vedi squadra.md). Cancellare il profilo azzera anche quel valore pubblico.
  • Luogo di nascita
  • Indirizzo di residenza
  • Telefono
  • Email

Documento di identità

Campi.

  • Tipo documento
  • Numero documento
  • Rilasciato da
  • Data emissione
  • Data scadenza

Upload.

  • Foto fronte
  • Foto retro

Certificato medico

Campi.

  • Data di scadenza

Upload.

  • Certificato medico

Il giocatore può aggiornare liberamente sia la data sia il file.

Quando mancano 30 giorni o meno alla scadenza, o il certificato è scaduto, il giocatore riceve un avviso nella propria Home; compare in quello degli admin da 7 giorni prima (vedi Avviso certificati).

Lo storico non viene mantenuto nella prima versione.

Foto tessera

Rimossa (DD-044, migration m29): il profilo non chiede più la foto tessera e la colonna foto_path non esiste più. I file già caricati sono stati cancellati dal bucket.

Statistiche

Sezione già presente. Contiene.

  • Presenze
  • Voto medio
  • MVP
  • Serie
  • Altre statistiche disponibili

Badge

Sezione già presente.

Contiene tutti i badge ottenuti e quelli ancora da sbloccare.

Opzioni

Contiene.

  • Logout
  • Preferenze notifiche: un solo interruttore che iscrive il dispositivo a tutte le push (turno palloni, solleciti presenze) e abilita le notifiche smart in app — non è limitato ai soli palloni (vedi Notifiche)
  • Impostazioni applicazione
  • Segnala un bug e Suggerisci una nuova funzionalità: due link che aprono una issue GitHub già impostata sul template giusto (.github/ISSUE_TEMPLATE/bug_report.yml e feature_request.yml). Nessun dato passa dall'app — la segnalazione vive interamente su GitHub, così non servono né una tabella né una schermata di gestione.

Dashboard amministratore

Gli amministratori dispongono di una schermata dedicata (/admin, raggiungibile da Profilo → Opzioni), organizzata in tab scorrevoli a pillole (BarraSottosezioni, stesso componente di Squadra e Campionato): Squadra, Profili, Disattivati (solo se c'è almeno un giocatore disattivato) e Notifiche.

La tab Notifiche mostra quanti giocatori attivi hanno almeno un dispositivo iscritto alle notifiche push e i loro nomi, leggendo GET /api/public/notifiche-attive (vedi Notifiche). È solo consultiva: l'attivazione resta un gesto che ogni giocatore deve fare dal proprio dispositivo (Profilo), l'admin non può attivarla per conto di altri.

Gli allenatori stanno nella stessa tab in un gruppo «Allenatori» a parte, senza documenti né tesseramento, e non entrano nei conteggi della tab Squadra né nell'export CSI (DD-034).

Per ogni giocatore, nella tab Profili, vengono mostrati.

  • Stato del profilo
  • Certificato medico
  • Documento di identità
  • Stato tesseramento CSI (tesserato / da tesserare)

Azioni disponibili.

  • Visualizza profilo (la scheda si apre in linea nell'elenco: nessuna schermata separata)
  • Scarica certificato
  • Scarica documento
  • Modifica dati squadra e dati personali del giocatore (DD-017)
  • Registra numero e data della tessera CSI, una volta arrivata dal comitato
  • Scollega account, per liberare uno slot assegnato per errore
  • Aggiungi giocatore, per inserire un nuovo membro della squadra
  • Disattiva/Riattiva giocatore, per chi lascia la squadra (o rientra)

Esportazione CSI

Gli amministratori possono esportare un file CSV contenente esclusivamente i dati richiesti per il tesseramento.

Campi esportati.

  • Nome
  • Cognome
  • Data di nascita
  • Luogo di nascita
  • Indirizzo
  • Telefono
  • Email
  • Tipo documento
  • Numero documento
  • Rilasciato da
  • Data emissione
  • Data scadenza

Tracciamento tesseramento

Numero e data della tessera CSI non sono dati che il giocatore conosce in anticipo: arrivano dal comitato dopo l'iscrizione effettiva. Per questo, a differenza dei dati personali del profilo, li scrive solo un amministratore — come nome, cognome, numero di maglia e ruolo (DD-017), il trigger sulla tabella li rende non modificabili dal giocatore stesso. La dashboard mostra un badge "Tesserato"/"Da tesserare" su ogni scheda e il conteggio complessivo della squadra.

Completamento profilo

Ogni sezione contribuisce alla percentuale di completamento.

Sezione Peso
Dati personali 34%
Documento di identità 33%
Certificato medico 33%

Quando tutte le sezioni risultano complete il profilo raggiunge il 100%.

Permessi

Giocatore — può modificare esclusivamente il proprio profilo.

Amministratore — può visualizzare tutti i profili, scaricare tutti i documenti, esportare i dati, modificare dati squadra e dati personali di chiunque e scollegare un account (DD-017). Non carica file al posto di altri.

Avviso certificati — il giocatore vede solo il proprio, l'admin i nomi di tutta la rosa, nessun altro ne vede (vedi Avviso certificati).

Versione 1

  • Profilo giocatore
  • Completamento profilo
  • Gestione dati personali
  • Documento di identità
  • Certificato medico
  • Dashboard amministratore
  • Esportazione CSV CSI

Versioni future

  • Storico certificati medici
  • Avviso certificati anche via push, o con una soglia regolabile dall'admin (DD-035, Riesame)
  • Gestione documenti aggiuntivi
  • Consensi privacy
  • Firma digitale
  • Verifica automatica documenti