diff --git a/src/components/admin/round/ranking-dashboard.tsx b/src/components/admin/round/ranking-dashboard.tsx index 4b29132..3f63ec9 100644 --- a/src/components/admin/round/ranking-dashboard.tsx +++ b/src/components/admin/round/ranking-dashboard.tsx @@ -1136,6 +1136,28 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran )} Score: {a.evaluation?.globalScore?.toFixed(1) ?? '—'} + {useBalanced && (() => { + const userId = a.user?.id + const score = a.evaluation?.globalScore + if (!userId || score == null) return null + const stats = evalScores?.jurorStats?.[userId] + const overallMean = evalScores?.overallMean + const overallStddev = evalScores?.overallStddev + if (!stats || overallMean == null || overallStddev == null || overallStddev === 0) return null + const z = stats.stddev > 0 + ? (score - stats.mean) / stats.stddev + : (score - overallMean) / overallStddev + const contributesAs = overallMean + z * overallStddev + return ( + e.stopPropagation()} + > + typical {stats.mean.toFixed(2)} → contributes {contributesAs.toFixed(2)} + + ) + })()} {isExpanded && a.evaluation?.feedbackText && ( diff --git a/src/server/routers/ranking.ts b/src/server/routers/ranking.ts index 2e1e5dd..5757c9a 100644 --- a/src/server/routers/ranking.ts +++ b/src/server/routers/ranking.ts @@ -537,6 +537,19 @@ export const rankingRouter = router({ } } - return { byProject, balanced } + // Per-juror grading stats so the side panel can render each juror's + // personal baseline and rescaled contribution. + const jurorStats: Record = {} + for (const [userId, s] of balanceCtx.jurorStats.entries()) { + jurorStats[userId] = { mean: s.mean, stddev: s.stddev, count: s.count } + } + + return { + byProject, + balanced, + jurorStats, + overallMean: balanceCtx.overallMean, + overallStddev: balanceCtx.overallStddev, + } }), })