Sistema i buchi del badge Pagellone: soglia minima voti e voto limitato ai convocati

Il badge Pagellone si sblocca ora solo con almeno 5 pagelle ricevute
(VOTI_MINIMI_PAGELLA): un voto solo poteva sbloccarlo o farlo sparire senza
significatività statistica. Aggiunto Giocatore.votiPagella per farlo funzionare.

La migration m13 (DD-027) estende le policy RLS di M11 su pagelle_voti, mvp_voti e
badge_social_voti: votante e votato devono essere convocati all'evento (prima solo
un filtro applicativo), e per le pagelle anche pagelle_chiuse=false. Le policy
admin restano permissive di proposito. Applicata anche al progetto cloud.

Copertura test completa: unit sulla soglia minima, integration sulle nuove policy
RLS (permessi.test.ts) e un end-to-end reale (pagella-badge.test.ts) sul modello
di mvp-badge.test.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-08 14:08:52 +02:00
co-authored by Claude Sonnet 5
parent 8c9cf370e8
commit 080379cc64
14 changed files with 548 additions and 34 deletions
+28 -1
View File
@@ -25,6 +25,7 @@ function g(valori: Partial<Giocatore> = {}): Giocatore {
presenze: 0,
mvp: 0,
mediaVoto: 0,
votiPagella: 0,
palloni: 0,
cacche: 0,
cacchePartita: 0,
@@ -66,6 +67,29 @@ const pagella = badgeDefs.find((b) => b.id === "pagella")!;
assert.equal(gradoRaggiunto(pagella, 6.4), null);
assert.equal(gradoRaggiunto(pagella, 6.5), "bronzo");
// Sotto i voti minimi il badge resta bloccato anche con una media altissima: un voto solo
// non deve poter sbloccare/sfilare Pagellone.
assert.equal(
statoBadge(pagella, g({ mediaVoto: 10, votiPagella: 1 })).grado,
null,
"1 voto su 10: non basta, sotto la soglia minima",
);
assert.equal(
statoBadge(pagella, g({ mediaVoto: 10, votiPagella: 4 })).grado,
null,
"4 voti: ancora sotto la soglia minima (5)",
);
assert.equal(
statoBadge(pagella, g({ mediaVoto: 10, votiPagella: 5 })).grado,
"oro",
"5 voti: la soglia minima è raggiunta, la media conta",
);
assert.equal(
statoBadge(pagella, g({ mediaVoto: 6.5, votiPagella: 5 })).grado,
"bronzo",
"sopra la soglia minima, valgono le normali soglie di grado",
);
// --- badgeGiocatore ----------------------------------------------------------
assert.equal(badgeGiocatore(g()).length, badgeDefs.length, "i badge normali sono sempre tutti");
assert.ok(
@@ -116,7 +140,9 @@ assert.equal(vuota.sbloccati.length, 0);
assert.equal(vuota.inProgresso.length, badgeDefs.length);
assert.equal(vuota.nascosti, badgeSegreti.length);
const piena = collezioneBadge(g({ mvp: 5, mediaVoto: 8, presenze: 30, infortuni: 3 }));
const piena = collezioneBadge(
g({ mvp: 5, mediaVoto: 8, votiPagella: 5, presenze: 30, infortuni: 3 }),
);
assert.equal(
piena.ottenuti,
piena.sbloccati.length + piena.segreti.length,
@@ -133,6 +159,7 @@ assert.equal(
g({
mvp: 5,
mediaVoto: 10,
votiPagella: 5,
palloni: 10,
presenze: 30,
serieAllenamenti: 10,