From fb8e672f77db743ed8e0849f2640f1a8e178fc70 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 03:16:51 +0000 Subject: [PATCH] Address code review: type hygiene, explicit types, parallel fetching, style fix - Remove teamOwnerId from TeamStanding type (was an internal server concern, not display data) - Remove teamOwnerId from getSeasonStandings return value - Add TeamStandingWithChange interface extending TeamStanding with sevenDayRankChange/sevenDayOldRank fields - Annotate getSevenDayStandingsChange with explicit Promise return type - Re-export TeamStandingWithChange from models/standings.ts - Standings loader: query teams table directly for ownerIds instead of relying on teamOwnerId in standings data - Standings loader: parallelize all independent queries (standings, teams, progressionData, seasonComplete, completionPercentage) with Promise.all - Restore font-medium on StandingsTable team TableCell https://claude.ai/code/session_01EYgGnuTBaRVdBDapJRTxDZ --- app/components/standings/StandingsTable.tsx | 2 +- app/models/standings.ts | 7 ++- .../leagues/$leagueId.standings.$seasonId.tsx | 52 ++++++++++--------- app/types/standings.ts | 6 ++- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/app/components/standings/StandingsTable.tsx b/app/components/standings/StandingsTable.tsx index d981151..923671b 100644 --- a/app/components/standings/StandingsTable.tsx +++ b/app/components/standings/StandingsTable.tsx @@ -54,7 +54,7 @@ export function StandingsTable({ )} - + ({ teamId: standing.teamId, teamName: standing.team.name, - teamOwnerId: standing.team.ownerId, totalPoints: parseFloat(standing.totalPoints), currentRank: standing.currentRank, previousRank: standing.previousRank, @@ -292,7 +291,7 @@ export async function getTeamStandingsHistory( export async function getSevenDayStandingsChange( seasonId: string, providedDb?: ReturnType -) { +): Promise { const db = providedDb || database(); const sevenDaysAgo = new Date(); diff --git a/app/routes/leagues/$leagueId.standings.$seasonId.tsx b/app/routes/leagues/$leagueId.standings.$seasonId.tsx index 57b3187..4775dfa 100644 --- a/app/routes/leagues/$leagueId.standings.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.standings.$seasonId.tsx @@ -71,36 +71,38 @@ export async function loader(args: Route.LoaderArgs) { }); } - // Fetch standings with 7-day comparison - const standingsWithComparison = await getSevenDayStandingsChange(seasonId, db); + // Fetch standings, teams (for owner lookup), and independent data in parallel + const [standingsWithComparison, teams, progressionData, seasonComplete, completionPercentage] = + await Promise.all([ + getSevenDayStandingsChange(seasonId, db), + db.query.teams.findMany({ + where: eq(schema.teams.seasonId, seasonId), + columns: { id: true, ownerId: true }, + }), + getSeasonPointProgression(seasonId, db), + isSeasonComplete(seasonId, db), + getSeasonCompletionPercentage(seasonId, db), + ]); - // Fetch owner display names for all teams in standings - const ownerIds = [ - ...new Set( - standingsWithComparison - .map((s) => s.teamOwnerId) - .filter((id): id is string => id != null) - ), - ]; + // Build teamId -> ownerName map + const ownerIds = [...new Set(teams.map((t) => t.ownerId).filter((id): id is string => id != null))]; const userRows = await findUsersByClerkIds(ownerIds); const userByClerkId = new Map(userRows.map((u) => [u.clerkId, u])); + const ownerNameByTeamId = new Map( + teams + .filter((t): t is typeof t & { ownerId: string } => t.ownerId != null) + .map((t) => { + const user = userByClerkId.get(t.ownerId); + return [t.id, user ? getUserDisplayName(user) : null] as const; + }) + ); // Map to format expected by component (use sevenDayRankChange instead of previousRank) - const formattedStandings = standingsWithComparison.map((standing) => { - const user = standing.teamOwnerId ? userByClerkId.get(standing.teamOwnerId) : undefined; - return { - ...standing, - rankChange: standing.sevenDayRankChange, - ownerName: user ? getUserDisplayName(user) : null, - }; - }); - - // Fetch historical progression data - const progressionData = await getSeasonPointProgression(seasonId, db); - - // Check season completion status - const seasonComplete = await isSeasonComplete(seasonId, db); - const completionPercentage = await getSeasonCompletionPercentage(seasonId, db); + const formattedStandings = standingsWithComparison.map((standing) => ({ + ...standing, + rankChange: standing.sevenDayRankChange, + ownerName: ownerNameByTeamId.get(standing.teamId) ?? null, + })); return { league, diff --git a/app/types/standings.ts b/app/types/standings.ts index 9db236d..643df61 100644 --- a/app/types/standings.ts +++ b/app/types/standings.ts @@ -5,7 +5,6 @@ export interface TeamStanding { teamId: string; teamName: string; - teamOwnerId?: string | null; ownerName?: string | null; totalPoints: number; currentRank: number; @@ -34,3 +33,8 @@ export interface TeamStandingSnapshot { rank: number; totalPoints: number; } + +export interface TeamStandingWithChange extends TeamStanding { + sevenDayRankChange: number; + sevenDayOldRank: number | null; +}