Files
CRAPP/docs/modules/allenatore.md
T
davideandClaude Opus 5.5 dda4aff746 Documenta il ruolo allenatore (specifica, DD-034, roadmap)
L'allenatore è uno slot di giocatori_squadra con tipo diverso: registrato dall'admin
per email, gestisce gli eventi e sollecita le presenze, ha un profilo ridotto
(dati personali e foto, senza stagione e badge), compare in Rosa come «Allenatore»
e non vede badge né cacche. Solo documentazione, nessuna implementazione.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 14:23:12 +02:00

12 KiB

Modulo — Ruolo Allenatore

Stato: da implementare (specifica) Decisione: DD-034 File coinvolti (previsti): src/lib/ruoli.ts, src/lib/auth-route.server.ts, src/routes/profilo.tsx, src/routes/eventi.tsx, src/routes/admin.tsx, src/lib/profili-core.ts, i punti che leggono la rosa (vedi Esclusione dalla rosa)

Obiettivo

Dare accesso all'app all'allenatore, con permessi diversi da quelli di un giocatore: gestisce gli eventi (allenamenti, partite, amichevoli) e sollecita le presenze, ma non gioca: compare in Squadra come membro con la dicitura «Allenatore», però non è convocabile, non vota, non riceve voti e non ha statistiche, badge o stagione.

Registrazione

Stesso flusso dei giocatori (DD-018), senza passaggi in più:

  1. L'admin, da /admin → Aggiungi, sceglie il tipo Allenatore invece di Giocatore e inserisce nome, cognome ed email Gmail. Numero di maglia e ruolo in campo non si chiedono.
  2. L'allenatore accede con Google; l'email corrisponde allo slot e il collegamento è automatico. Se l'email non corrisponde, stesso messaggio di errore dei giocatori.
  3. Entra in Home.

Il permesso nasce dalla registrazione fatta dall'admin: l'allenatore non può auto-promuoversi, perché il tipo dello slot lo scrive solo un admin (come oggi numero e ruolo).

Profilo

Il profilo dell'allenatore ha solo due tab (in TAB_PROFILO oggi sono quattro):

Tab Giocatore Allenatore
Stagione sì no
Badge sì no
Documenti sì sì, ridotta (vedi sotto); tab iniziale
Impostazioni sì sì, identica (logout, notifiche, segnalazioni)

Un link diretto a /profilo?tab=stagione o ?tab=badge apre Documenti.

Dati modificabili dall'allenatore

Campo Dove sta oggi Nota
Nome, cognome giocatori_squadra per un giocatore li scrive solo l'admin; per l'allenatore anche lui sul proprio slot
Email (contatto) profili_giocatore.email non è l'email di login, che resta quella registrata dall'admin
Data di nascita profili_giocatore.data_nascita sincronizzata in giocatori_squadra.nascita come per tutti (DD-031): compleanno in Calendario
Luogo di nascita profili_giocatore.luogo_nascita
Telefono profili_giocatore.telefono
Foto profilo bucket avatar-giocatori stesso cerchio avatar e stesso upload dei giocatori

Non si mostrano: indirizzo di residenza, documento d'identità, certificato medico, foto tessera, tesseramento CSI.

Completamento profilo

Per l'allenatore il completamento conta solo i dati personali della tabella sopra (100%). Il widget in Home segue la stessa regola: sparisce quando quei campi sono compilati.

Squadra

L'allenatore compare nella tab Rosa insieme ai giocatori, con foto, nome e cognome. Dove per un giocatore c'è il ruolo in campo (palleggiatore, schiacciatore…) per lui c'è scritto Allenatore, ricavato da tipo e non dal campo ruolo. Non ha numero di maglia né statistiche, e non compare nella tab Stats né nelle classifiche.

Da allenatore, in /squadra vede solo Rosa e Stats. Le tab Obiettivi e Badge non compaiono, e un link diretto a una delle due apre Rosa.

Tab Giocatore Allenatore
Rosa sì sì
Stats sì sì
Obiettivi sì no
Badge sì no

Badge e cacche nascosti

L'allenatore non vede nessun badge e nessuna classifica o dato sulle cacche, in nessuna schermata:

Dove Cosa si nasconde all'allenatore
/squadra → Stats il criterio di ordinamento «Cacche» (cacchePartita)
/squadra → Rosa, scheda giocatore la riga «Cacche/partita 💩»
/partita/$id la sezione «Badge votati dai compagni» e il sondaggio cacche (SondaggioCacche)
/profilo, /squadra le tab Badge (già escluse sopra)

Presenze, media voto, MVP e palloni restano visibili.

Gestione eventi

L'allenatore ha su /eventi gli stessi poteri dell'admin: crea, modifica, sposta ed elimina eventi e sceglie i convocati. Nel database la policy di scrittura su eventi_app passa da "solo admin" a "admin o allenatore" (oggi m11_scritture_per_ruolo); la cancellazione a cascata (DD-029) resta invariata.

Il link a /eventi compare dove oggi compare per l'admin.

Può anche sollecitare le presenze di un evento, come l'admin: la route sollecita-presenze.ts accetta admin o allenatore (oggi richiediAdmin()), e il sollecito arriva solo ai giocatori che non hanno risposto, mai all'allenatore stesso.

Restano solo admin: dashboard /admin, dati e documenti dei giocatori, export CSI, notifica personalizzata, promemoria palloni, apertura sondaggio cacche, correzione delle risposte presenze altrui, gestione dei ruoli.

Notifiche

L'allenatore riceve i promemoria degli eventi (24h e 3h prima, push e centro notifiche in-app) come i giocatori, anche se non è convocato, e può attivare le push dal proprio Profilo. Non riceve il sollecito presenze né il turno palloni, che riguardano chi gioca.

Esclusione dalla rosa

L'allenatore ha uno slot in giocatori_squadra (DD-034), quindi ogni lettura della "rosa di gioco" deve escluderlo: oggi il filtro è attivo, diventa attivo e tipo = giocatore. Fanno eccezione la tab Rosa di Squadra, i compleanni del Calendario e i destinatari dei promemoria evento, che lo includono. Punti da coprire, da verificare uno per uno in implementazione:

  • client: useRosa(), useGiocatoriSquadra() (dove usata come rosa), useAnagraficaRosa() — Squadra (Stats, Obiettivi, Badge), Presenze, Palloni, Pagelle, MVP, Badge, Classifica, Scout, form convocati di /eventi;
  • server e condivisi: leggiGiocatoriSquadra(), convocatiEvento() (eventi.ts, riceve la rosa già filtrata), route API che notificano "tutta la rosa";
  • database: evento_permette_voto() (M13), che con convocati vuoto intende "tutta la rosa attiva"; i cron dei promemoria evento (M17) invece aggiungono sempre l'allenatore ai destinatari, convocato o no;
  • admin: tab Profili (conteggi di completamento e tesseramento), export CSI.

Il compleanno dell'allenatore resta visibile in Calendario (è un membro della squadra, non un giocatore).

Azione Giocatore Allenatore Admin
Modificare nome e cognome no sì, i propri tutti
Dati personali e foto profilo i propri i propri (ridotti) tutti (non i file)
Documento, certificato, foto tessera i propri — lettura/download
Creare/modificare/eliminare eventi, convocati no sì sì
Sollecitare le presenze no sì sì
Promemoria palloni, notifica personalizzata no no sì
Rispondere alle presenze, votare, essere votato sì no sì (se giocatore)
Tab Stagione e Badge del profilo sì no sì
Tab Obiettivi e Badge di Squadra sì no sì
Badge e classifiche/dati sulle cacche sì no sì
Dashboard /admin no no sì

Cosa implementare

  1. Migration (nuova, non si riscrivono le esistenti):
    • giocatori_squadra.tipo (giocatore | allenatore, default giocatore, non nullo);
    • valore allenatore nell'enum app_role, assegnato in user_roles da una funzione SECURITY DEFINER al momento del collegamento di uno slot con tipo = allenatore (i permessi restano letti da user_roles, DD-011);
    • trigger enforce_giocatori_squadra_update: tipo scrivibile solo dall'admin; nome e cognome scrivibili dall'allenatore sul proprio slot;
    • policy di scrittura eventi_app: admin o allenatore;
    • evento_permette_voto(): escludere tipo = allenatore;
    • cron promemoria evento: includere sempre gli allenatori attivi tra i destinatari.
  2. src/lib/ruoli.ts: useIsAllenatore() e usePuoGestireEventi() (admin o allenatore), stessa lettura di user_roles e stessa cache.
  3. /eventi: gate usePuoGestireEventi() al posto di useIsAdmin(), anche per il link di accesso. Il bottone del sollecito presenze usa lo stesso gate; lato server sollecita-presenze.ts passa da richiediAdmin() a un controllo "admin o allenatore" in auth-route.server.ts.
  4. /profilo: tab e campi in base al tipo; nome e cognome modificabili per l'allenatore.
  5. /squadra: l'allenatore compare in Rosa con la dicitura «Allenatore», senza numero né statistiche; da allenatore non si vedono le tab Obiettivi e Badge, né il criterio e la riga delle cacche. /partita/$id: niente sezione badge né sondaggio cacche per l'allenatore.
  6. profili-core.ts: completamento dedicato all'allenatore (solo dati personali).
  7. /admin: scelta del tipo in "Aggiungi"; allenatori mostrati a parte, fuori dai conteggi di completamento e tesseramento; nessun export CSI per loro.
  8. Filtro rosa in tutti i punti elencati sopra.
  9. Test: unit sul completamento e sul filtro rosa; integration in test/integration/permessi.test.ts (l'allenatore scrive eventi_app, non vota, non cambia il proprio tipo, non scrive slot altrui).
  10. Documentazione alla consegna: DATABASE.md (colonna, enum, tabella permessi), profilo-giocatore.md, squadra.md, calendario.md, CHANGELOG.md, ROADMAP.md, DD-034 → Accettata.

Scelte confermate

  • Riceve i promemoria degli eventi: sì.
  • Sollecita le presenze: sì. Promemoria palloni: no.
  • Badge e cacche: mai visibili all'allenatore, né classifiche né sondaggio.
  • In Squadra: nessuna sezione Staff; compare in Rosa come gli altri, con «Allenatore» al posto del ruolo.
  • Vede le risposte presenze e le pagelle dei giocatori: sì, la lettura è già aperta a tutti gli autenticati.