Applica una soglia minima di campione a Media voto e MVP in home (DD-028)

Rimuove l'hint statico "+2 questo mese" dalla StatTile Presenze. La StatTile
Media voto usa ora la stessa soglia minima di voti del badge Pagellone
(VOTI_MINIMI_PAGELLA), tramite la nuova funzione pura testabile
mediaVotoColpoDOcchio(). L'MVP di partita richiede un quorum minimo di 2
voti totali (VOTI_MINIMI_MVP) oltre al margine netto già richiesto: un
solo voto non assegna più la vittoria, con effetto anche sui conteggi
già mostrati. Aggiorna test unitari e di integrazione, e documenta la
decisione in DESIGN_DECISIONS.md, pagelle.md, mvp.md e CHANGELOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 09:56:56 +02:00
co-authored by Claude Sonnet 5
parent 6d177d5d8a
commit 00235d1594
12 changed files with 165 additions and 19 deletions
+17 -2
View File
@@ -6,6 +6,7 @@ import {
mvpVintiPerGiocatore,
vincitoriMvp,
votoMvpAperto,
VOTI_MINIMI_MVP,
type VotoMvp,
} from "@/lib/mvp-voti";
@@ -27,6 +28,7 @@ const partita = [
v("m1", "g3", "g2", "Bruno"),
v("m1", "g4", "g5", "Anna"),
v("m2", "g1", "g5", "Anna"),
v("m2", "g3", "g5", "Anna"),
];
assert.deepEqual(conteggioPartita(partita, "m1"), [
@@ -46,10 +48,18 @@ assert.deepEqual(
assert.deepEqual(vincitoriMvp(partita), { m1: "Bruno", m2: "Anna" });
assert.deepEqual(vincitoriMvp(pari), {}, "due voti pari: MVP non assegnato");
assert.deepEqual(vincitoriMvp([]), {});
// --- vincitoriMvp: quorum minimo di voti -------------------------------------
assert.equal(VOTI_MINIMI_MVP, 2, "un solo voto non deve mai bastare da solo");
assert.deepEqual(
vincitoriMvp([v("m4", "g1", "g2", "Solo")]),
{},
"un solo votante, senza concorrenza: sotto quorum, nessun MVP",
);
assert.deepEqual(
vincitoriMvp([v("m4", "g1", "g2", "Solo"), v("m4", "g3", "g2", "Solo")]),
{ m4: "Solo" },
"un solo votante basta se non c'è concorrenza",
"due voti allo stesso candidato: quorum raggiunto",
);
// Tre candidati: i primi due pari in testa, un terzo staccato. Deve restare senza MVP,
@@ -83,10 +93,15 @@ assert.deepEqual(
"la parità non assegna",
);
assert.deepEqual(
mvpVintiPerGiocatore([...partita, v("m5", "g1", "g2", "Bruno")]),
mvpVintiPerGiocatore([...partita, v("m5", "g1", "g2", "Bruno"), v("m5", "g3", "g2", "Bruno")]),
{ g2: 2, g5: 1 },
"i titoli si sommano su partite diverse",
);
assert.deepEqual(
mvpVintiPerGiocatore([...partita, v("m5", "g1", "g2", "Bruno")]),
{ g2: 1, g5: 1 },
"m5 ha un solo voto: sotto quorum, non conta",
);
assert.deepEqual(mvpVintiPerGiocatore([]), {});
// --- votoMvpAperto: due ore dopo il fischio d'inizio -------------------------
+15
View File
@@ -2,11 +2,13 @@
import assert from "node:assert/strict";
import {
mediaSquadra,
mediaVotoColpoDOcchio,
mediePagelle,
mieiVoti,
pagellePartita,
type VotoPagella,
} from "@/lib/pagelle";
import { VOTI_MINIMI_PAGELLA } from "@/lib/badges";
const voto = (
match_id: string,
@@ -61,4 +63,17 @@ assert.deepEqual(mieiVoti(voti, "m1", "g99"), {}, "chi non ha votato non ha voti
assert.equal(mediaSquadra(voti), 6.8, "(8+7+6+6)/4 = 6.75 → 6.8");
assert.equal(mediaSquadra([]), 0, "nessun voto: media zero, non NaN");
// --- mediaVotoColpoDOcchio: soglia minima per la StatTile home (DD-028) ------
assert.equal(
mediaVotoColpoDOcchio({ mediaVoto: 10, votiPagella: VOTI_MINIMI_PAGELLA - 1 }),
"—",
"sotto soglia: nascosta anche con media altissima",
);
assert.equal(
mediaVotoColpoDOcchio({ mediaVoto: 7.5, votiPagella: VOTI_MINIMI_PAGELLA }),
7.5,
"esattamente in soglia: la media conta",
);
assert.equal(mediaVotoColpoDOcchio({ mediaVoto: 0, votiPagella: 0 }), "—", "nessun voto ricevuto");
console.log("pagelle: ok");