Files
CRAPP/docs/decisions/DD-040.md
T
davideandClaude Sonnet 5.5 cdf8b144e2 Turno palloni: un solo avviso, 3 ore prima dell'evento (DD-042)
La migration m27 riduce il job automatico alla sola fascia delle 3 ore:
l'avviso arriva una volta a chi deve portare i palloni e a chi li deve
prendere. I tipi turno_palloni_12h e _6h restano ammessi per le notifiche
già generate e per la revoca. Migration applicata in produzione.

Test di integrazione aggiornati (nessun avviso a 4,5 e 9 ore); documentati
DD-042, moduli, DATABASE, ROADMAP, glossario e changelog.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 14:33:38 +02:00

7.4 KiB

DD-040 — Promemoria con «oggi» o «domani», turno palloni e solleciti automatici

Data: 30 settembre 2026
Stato: Accettata (implementata: migration m26, applicata in produzione il 30 settembre 2026, job, route e test). Il turno palloni è poi passato a un solo avviso a 3 ore da DD-042.

Contesto
Quattro notifiche su sei partivano da un pulsante premuto da un admin (DD-025 per i palloni): se nessuno lo premeva, nessuno veniva avvisato. I testi erano inoltre brevi e informali, e i promemoria non dicevano quando e dove. Si vuole che turno palloni e sollecito presenze partano anche da soli, a orari fissi prima dell'evento, e che i testi siano più formali e completi. I testi nuovi sono nel catalogo.

Decisione

  1. Promemoria a 24 e 3 ore: nuovo testo con data, ora e luogo. La parola nel titolo e nella riga «Data» è «domani» se la data dell'evento è quella di domani (fuso Europe/Rome), «oggi» altrimenti. Vale per entrambi i promemoria, quindi anche quello a 3 ore di un evento dopo la mezzanotte dice «domani». La parola la calcola la funzione SQL quando genera la notifica.
  2. Turno palloni automatico. Un job pg_cron ogni 15 minuti avvisa per gli eventi di tipo allenamento o partita, in tre tempi con finestre che non si sovrappongono: 12 ore (tra 12 e 6 ore prima dell'inizio), 6 ore (tra 6 e 3) e 3 ore (meno di 3). Parte solo se per l'evento c'è un incaricato confermato in turni_palloni: le proposte automatiche di completaTurni() non salvate non contano. Gli avvisi sono due, con lo stesso testo nei tre tempi: «incarico assegnato» all'incaricato e «riconsegna» a chi aveva i palloni all'evento precedente, se è un'altra persona.
    • Pulsante manuale. «Avvisa chi è di turno» e la route promemoria-palloni restano: tipo turno_palloni, testo nuovo, push mandata dalla route e non dalla coda. È una notifica in più; riceverne due (automatica e manuale) va bene.
    • Incaricato cambiato dopo un avviso. Il nuovo incaricato riceve il suo avviso al giro successivo, con il tipo della finestra in cui cade. Chi aveva già ricevuto un avviso e non è più destinatario riceve una sola volta «Turno palloni: incarico revocato» (turno_palloni_revocato), se l'evento non è iniziato. Il job lo scopre confrontando i destinatari attuali con il registro degli avvisi automatici già generati (non con le notifiche, che il giocatore può aver eliminato), senza trigger su turni_palloni. Gli avvisi del pulsante non contano: possono riguardare una proposta non confermata.
    • Niente email. Gli avvisi palloni (automatici, revoca e pulsante) arrivano come push e nel centro notifiche, non per email: il trigger notifiche_utente_accoda_email salta i tipi turno_palloni, turno_palloni_12h, _6h, _3h e turno_palloni_revocato. È un'eccezione a DD-038 («ogni notifica ha tre canali») solo per questi tipi; l'interruttore «Email» non cambia.
  3. Sollecito presenze automatico in tre tempi. Lo stesso job manda il sollecito 24 ore (tra 24 e 12 ore prima), 12 ore (tra 12 e 6) e 6 ore (meno di 6) prima, al massimo una notifica per giocatore e per tipo. Lo riceve solo chi in quel momento non ha risposto o ha risposto «forse» ed è destinatario dell'evento: i convocati, o tutta la rosa attiva se convocati è vuoto, mai l'allenatore. Chi risponde presente, assente o in ritardo smette di riceverli; chi resta su «forse» li riceve tutti e tre. Un evento creato a meno di 12 ore dall'inizio riceve solo il sollecito della sua finestra.
    • Pulsante manuale. «Sollecita» e la route sollecita-presenze restano, anche per l'allenatore: tipo sollecita_presenze, push mandata dalla route, testo nuovo con in più la riga «Richiesta di: Nome». I destinatari sono gli stessi dell'automatico (convocati senza risposta o con «forse»); oggi la route guarda invece tutti i giocatori attivi.
  4. Stessa infrastruttura dei promemoria (DD-037, DD-038): le notifiche automatiche nascono nel database, il registro promemoria_eventi_generati impedisce i doppioni anche se il giocatore le elimina, la push la manda il worker dalla coda notifiche_push_coda, l'email (quando c'è) nasce dal trigger su notifiche_utente. Tipi nuovi: sollecita_presenze_24h, _12h, _6h; turno_palloni_12h, _6h, _3h e turno_palloni_revocato. Il turno_palloni del pulsante resta.
  5. Migration m26: estende i CHECK sui tipi di notifiche_utente e del registro, il trigger della coda push, il trigger della coda email (che salta i tipi dei palloni) e ridefinisce la funzione dei promemoria. Le funzioni nuove riusano giocatori_destinatari_evento().

Alternative scartate

  • Togliere i pulsanti manuali (turno palloni e sollecito) una volta arrivati gli automatici → scartata su indicazione esplicita: servono all'admin per rimandare un avviso o sollecitare fuori dagli orari fissi.
  • Mandare tutti i solleciti (o gli avvisi palloni) a un evento creato tardi → scartata: più messaggi nel giro di pochi minuti sono rumore.
  • «Domani» e «oggi» fissi nei due testi → scartata: il job delle 24 ore scatta anche per eventi che iniziano oggi, e quello delle 3 ore attraversa la mezzanotte.
  • Calcolare il testo nell'app invece che nel database → scartata: le notifiche nascono nei job pg_cron, che non chiamano l'app (DD-038).
  • Spostare nel worker il calcolo di evento precedente e successivo dei palloni → scartata: un secondo punto che scrive in notifiche_utente, per un vantaggio piccolo.
  • Ritirare l'avviso già consegnato al vecchio incaricato → scartata: per la push non si può, e in-app confonde. Si manda la revoca.

Conseguenze

  • Cambia la regola «quattro notifiche su sei dipendono da un gesto manuale»: restano solo manuali il messaggio dello staff e il sondaggio pre-partita; per turno palloni e sollecito gli automatici si aggiungono ai pulsanti, e un giocatore può ricevere lo stesso avviso due volte.
  • Logica duplicata: «evento precedente» e «evento successivo» per i palloni, in palloni-core.ts (usato dal pulsante e dalla schermata), sono riscritti in SQL per i job (genera_avvisi_palloni_fascia). Ordine comune: data, ora, id. Se si cambia una regola in una sola delle due versioni, pulsante e job danno risposte diverse: notifiche-automatiche.test.ts confronta testi e destinatari sugli stessi dati, anche a parità di data e ora.
  • destinatariSollecito() riceve anche i convocati e serve al sollecito manuale; un giocatore non convocato non è più sollecitato. avvisiPalloniEvento() resta come riferimento per i test finché il SQL non la sostituisce del tutto.
  • Se un incaricato revocato viene poi riassegnato non riceve un secondo avviso, perché il registro lo ha già generato per quella finestra: la revoca resta l'ultima notifica che ha letto.
  • Le mail automatiche per evento e giocatore sono al massimo cinque (due promemoria, tre solleciti), più quelle dei pulsanti (sollecito, sondaggio). Il turno palloni non ne manda.
  • Il testo dei promemoria già generati non cambia (il registro impedisce di rigenerarli).

Riesame
Dopo la prima stagione di uso: se i solleciti o gli avvisi palloni risultano troppi, ridurre le finestre o escludere chi ha risposto «forse» più di una volta.