Calcola davvero le serie di presenze e sblocca badge e obiettivo.

I tre contatori (serieAllenamenti, seriePartite, serieConferme) e streak erano
zero fisso in useRosa(): la sezione Serie di presenze del profilo mostrava sempre
progresso nullo, i badge legati alla costanza erano impossibili da sbloccare e
l'obiettivo Continuita di squadra restava a 0/12.

serieConsecutiva() e serieConferme() (src/lib/presenze.ts) derivano le serie dagli
eventi passati e da risposte_presenze gia in cache, senza query aggiuntive.

Migration m9: nuova colonna risposto_il con l'istante della prima risposta, resa
immutabile da un trigger, confrontata con eventi_app.creato_il per le conferme
entro 24 ore. Serviva perche aggiornato_il registra l'ultima modifica, quindi chi
rispondeva subito e cambiava idea dopo risultava lento.

Corregge anche la barra di progresso, che misurava valore/prossimo e tornava
indietro a ogni traguardo raggiunto (2/3 = 67%, poi 3/6 = 50%).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 22:46:04 +02:00
co-authored by Claude Opus 5
parent 952f7b43d3
commit 7237e8ff39
12 changed files with 559 additions and 54 deletions
+6 -1
View File
@@ -20,6 +20,9 @@ export type Evento = {
casa: boolean;
/** Le pagelle di questa partita non accettano più voti. */
pagelleChiuse: boolean;
/** Quando l'evento è stato creato: è l'istante della convocazione.
* Assente sugli eventi generati dal client (compleanni, bozze non salvate). */
creatoIl?: string | undefined;
};
export type RigaEvento = {
@@ -34,6 +37,7 @@ export type RigaEvento = {
campionato: boolean;
casa: boolean | null;
pagelle_chiuse: boolean;
creato_il?: string;
};
/** Conversione riga database -> modello applicativo (riusabile anche lato server). */
@@ -50,11 +54,12 @@ export function daRiga(r: RigaEvento): Evento {
campionato: !!r.campionato,
casa: r.casa ?? true,
pagelleChiuse: !!r.pagelle_chiuse,
creatoIl: r.creato_il,
};
}
const COLONNE =
"id, tipo, titolo, luogo, data, ora, note, convocati, campionato, casa, pagelle_chiuse";
"id, tipo, titolo, luogo, data, ora, note, convocati, campionato, casa, pagelle_chiuse, creato_il";
/** Categoria mostrata in interfaccia: le amichevoli sono partite fuori campionato. */
export type CategoriaEvento = "allenamento" | "partita" | "amichevole" | "evento";