fix: sort ranking display by compositeScore, fix threshold cutoff line
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m41s

- Sort deduped ranking entries by compositeScore descending during
  localOrder init — ensures correct display order for both formula
  and old AI snapshots
- Fix threshold cutoff: scan forward to find first non-qualifying
  project instead of backward scan that left non-qualifying projects
  above the line

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-02 20:43:49 +01:00
parent cb688ba3e6
commit 761a203063

View File

@@ -425,7 +425,12 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
const dedupedStartup = dedup(startup) const dedupedStartup = dedup(startup)
const dedupedConcept = dedup(concept) const dedupedConcept = dedup(concept)
// Track original AI order for override detection (same effect = always in sync) // Sort by compositeScore descending — ensures display order matches the formula
// regardless of how the snapshot was originally generated (AI vs formula).
dedupedStartup.sort((a, b) => b.compositeScore - a.compositeScore)
dedupedConcept.sort((a, b) => b.compositeScore - a.compositeScore)
// Track original order for override detection (same effect = always in sync)
const order: Record<string, number> = {} const order: Record<string, number> = {}
dedupedStartup.forEach((r, i) => { order[r.projectId] = i + 1 }) dedupedStartup.forEach((r, i) => { order[r.projectId] = i + 1 })
dedupedConcept.forEach((r, i) => { order[r.projectId] = i + 1 }) dedupedConcept.forEach((r, i) => { order[r.projectId] = i + 1 })
@@ -938,10 +943,17 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
let cutoffIndex = -1 let cutoffIndex = -1
if (isThresholdMode) { if (isThresholdMode) {
// Find the LAST index in the list where the project meets the threshold // Find the FIRST project that does NOT meet the threshold — cutoff goes before it.
for (let i = localOrder[category].length - 1; i >= 0; i--) { // Works correctly when list is sorted by compositeScore (which correlates with avgGlobalScore).
const e = rankingMap.get(localOrder[category][i]) const firstFailIdx = localOrder[category].findIndex((id) => {
if ((e?.avgGlobalScore ?? 0) >= threshold) { cutoffIndex = i; break } const e = rankingMap.get(id)
return (e?.avgGlobalScore ?? 0) < threshold
})
if (firstFailIdx === -1) {
// All meet threshold — cutoff after the last one
cutoffIndex = localOrder[category].length - 1
} else if (firstFailIdx > 0) {
cutoffIndex = firstFailIdx - 1
} }
} else if (advanceCount > 0) { } else if (advanceCount > 0) {
cutoffIndex = advanceCount - 1 cutoffIndex = advanceCount - 1