P0-3a: dedupe the Explore leaderboard — one row per player+market + per-market cap
Phone audit: leaderboard flooded with 9 consecutive identical 'stolen_bases U0.5 45% B' rows. New shared lib/playerGrouping (dedupeLeaders + groupIntoLadders, name-key aware, 7 unit tests): ONE row per (player, market family) keeping the best-ranked, then a per-market cap (4) so no single prop type floods the board. Applied to ExploreHub. Ledger cards + Consensus grouping follow in P0-3b/c using the same lib. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { useEffect, useMemo, useState } from 'react';
|
||||
import SportBadge from '@/components/vyndr/SportBadge';
|
||||
import GradeBadge from '@/components/vyndr/GradeBadge';
|
||||
import { playerHref } from '@/lib/playerHref';
|
||||
import { dedupeLeaders } from '@/lib/playerGrouping';
|
||||
|
||||
/**
|
||||
* ExploreHub (Session 42 leaders; Session 60 night2/C — THE AGGREGATOR).
|
||||
@@ -54,7 +55,11 @@ export default function ExploreHub() {
|
||||
|
||||
const rows = useMemo(() => {
|
||||
const q = query.trim().toLowerCase();
|
||||
return q ? leaders.filter((l) => (l.player || '').toLowerCase().includes(q)) : leaders;
|
||||
const filtered = q ? leaders.filter((l) => (l.player || '').toLowerCase().includes(q)) : leaders;
|
||||
// P0-3 — ONE row per player+market family + a per-market cap, so a player's
|
||||
// alt-line ladder (Bohm ×3) collapses to one entry and no single prop type
|
||||
// (9× stolen_bases) can flood the ranked board.
|
||||
return dedupeLeaders(filtered, 4) as Leader[];
|
||||
}, [leaders, query]);
|
||||
|
||||
// Wave 2B — never-dark hub. When the selected sport is in its OFF-SEASON, the
|
||||
|
||||
Reference in New Issue
Block a user