Files
CRAPP/docs/decisions/DD-050.md
T
davideandClaude Sonnet 5.5 f0e6a3a6cc Documenta DD-050: avviso ad admin e allenatori se una presenza cambia a meno di 6 ore dall'evento
Solo documentazione: nessun codice né migration. Decisione in valutazione.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 17:47:12 +02:00

4.8 KiB

DD-050 — Avviso a admin e allenatori se una presenza cambia a meno di 6 ore dall'evento

Data: 8 ottobre 2026
Stato: In valutazione (solo documentata: nessun codice né migration scritti)

Contesto
Un giocatore può cambiare la risposta a un evento fino all'ultimo minuto. Chi organizza (admin e allenatore) se ne accorge solo riaprendo l'evento: un «assente» detto due ore prima di una partita può far saltare la formazione o il numero minimo per l'allenamento. Oggi nessuna notifica avvisa chi gestisce gli eventi di una risposta (notifiche.md, «Cosa non genera nessuna notifica»).

Decisione

  1. Cosa fa scattare l'avviso. Una riga di risposte_presenze che cambia — nuova, modificata o ritirata — quando mancano da 0 a 6 ore all'inizio di una partita o un allenamento (non agli altri tipi di evento). Scatta per qualsiasi cambio di stato, da qualunque valore a qualunque altro (presente, assente, forse, in ritardo, infortunato) e anche per la prima risposta e per il ritiro; non scatta solo se lo stato resta quello di prima (nessun cambio reale). Vale per qualunque giocatore, anche se la modifica la fa un admin per conto suo.

  2. Chi la riceve: gli admin e gli allenatori attivi (chi ha il ruolo admin o allenatore in user_roles e uno slot attivo in giocatori_squadra), tranne la persona a cui appartiene la presenza (se un admin cambia la propria, non avvisa se stesso). Chi ha il ruolo ma nessuno slot collegato non può ricevere notifiche, perché notifiche_utente è per slot.

  3. Come funziona. Un trigger AFTER INSERT OR UPDATE OF stato OR DELETE su risposte_presenze chiama una funzione SECURITY DEFINER (avvisa_presenza_modificata(), migration m32). La funzione:

    1. ignora il caso in cui lo stato prima e dopo è lo stesso;
    2. legge l'evento e continua solo se tipo è partita o allenamento e inizio_evento(data, ora) - now() sta tra 0 e 6 ore (stessa inizio_evento() di M26: fuso Europe/Rome, ora illeggibile = nessun avviso);
    3. inserisce una riga in notifiche_utente per ogni destinatario, con il tipo nuovo presenza_modificata.

    Dal database in poi il resto è già fatto: il trigger di M22/M26 accoda l'email, il trigger delle push (esteso con il tipo nuovo) accoda la push, la riga è il centro notifiche in-app (DD-038). Nessuna route dell'app e nessun codice lato client oltre al nuovo valore di TipoNotifica.

  4. Testo. Titolo Presenza modificata: <Nome Cognome>; corpo su righe: Evento: <titolo>, Data: <GG/MM/AAAA>, ore <ora>, Da: <stato prima>, A: <stato dopo>. Gli stati sono «presente», «assente», «forse», «in ritardo», «infortunato», «nessuna risposta» (prima di una risposta nuova, o dopo un ritiro). Non c'è un link all'evento: il pulsante «Apri CrAPP» della mail e il tocco sulla push aprono l'app.

  5. Una notifica per modifica, senza raggruppare. evento_id resta NULL (come i messaggi admin), così la UNIQUE (giocatore_id, evento_id, tipo) non si applica e due modifiche dello stesso evento non si sovrascrivono. Contro: se la stessa persona cambia idea cinque volte, ognuno dei destinatari riceve cinque notifiche e cinque email.

  6. Nessuna configurazione. Né una soglia modificabile (6 ore è scritto nella funzione), né un interruttore per ruolo: l'email e la push seguono le preferenze già esistenti di ciascuno (preferenze_utente, DD-036).

Alternative scartate

  • Una route dell'app invocata dal client dopo il salvataggio (come sollecita-presenze) → il client scrive su risposte_presenze direttamente con RLS: una route in più sarebbe aggirabile e dipenderebbe dal fatto che l'app sia ancora aperta al momento del salvataggio. Il trigger copre ogni scrittura.
  • Raggruppare in una sola notifica per evento (upsert con evento_id) → perde il dettaglio di chi ha cambiato cosa, e l'upsert non rifa partire la push (il trigger delle push è solo INSERT).
  • Notificare anche chi ha il ruolo ma è il giocatore stesso → inutile: sa già cosa ha fatto.

Conseguenze

  • Nuova migration m32 (CHECK dei tipi, due funzioni, due trigger); docs/DATABASE.md e il catalogo in notifiche.md si aggiornano con essa. Va applicata in produzione con npx supabase db push.
  • L'allenatore, che oggi non riceve nulla sulle presenze, riceve questa notifica: va aggiunta a allenatore.md.
  • Rumore possibile a ridosso dell'evento (punto 5). Se in pratica dà fastidio, il primo ritocco è raggruppare per evento, non togliere l'avviso.

Riesame
Dopo qualche settimana d'uso: se arrivano troppe notifiche per lo stesso giocatore, raggruppare; se 6 ore sono troppe o poche, spostare la soglia (una costante nella funzione).