Phase 2: scoring engine with full branch coverage

Pure functions in src/lib/scoring implementing docs/SCORING.md: cell values
(override > judge average), weighted raw totals, raw and placement points
with tie averaging, and competition-ranked standings. Coverage thresholds
are enforced at 100% for the module. Also silences the hydration warning
caused by browser extensions modifying <html>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 13:33:21 +02:00
co-authored by Claude Opus 5.5
parent bc8e4f3f5a
commit 84dfe6a54b
11 changed files with 670 additions and 3 deletions
+2 -1
View File
@@ -3,7 +3,7 @@
All implemented in `src/lib/scoring/` as pure functions. Tests must cover every rule below.
## 1. Cell value (team × criterion)
- **Direct game:** the admin score row. Missing → not scored.
- **Direct game:** the admin score row. Missing → not scored. Judge rows (e.g. left over from a mode switch) are ignored.
- **Judged game:**
- If an admin override row exists → use it.
- Else average of non-revoked judges' values for that cell. Missing judges are ignored (not zero).
@@ -12,6 +12,7 @@ All implemented in `src/lib/scoring/` as pure functions. Tests must cover every
## 2. Team raw score for a game
`raw = Σ (cellValue × criterion.weight)` over scored criteria.
A team with zero scored cells is **unscored** for that game (not 0).
`raw` is rounded to 6dp before ranking so float noise from averaging can't break a real tie.
## 3. Game points
- **raw mode:** `points = round2(raw × multiplier)`.