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>
192 lines
12 KiB
Markdown
192 lines
12 KiB
Markdown
# Modulo — Ruolo Allenatore
|
|
|
|
**Stato:** da implementare (specifica)
|
|
**Decisione:** [DD-034](../DESIGN_DECISIONS.md#dd-034--lallenatore-è-uno-slot-della-squadra-con-tipo-diverso-non-un-giocatore)
|
|
**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](#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).
|
|
|
|
## Permessi (riepilogo)
|
|
|
|
| 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.
|