Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/services/leaderboard/team/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"lateral".players
FROM team_pantheon_custom_race_leaderboard
LEFT JOIN LATERAL (
SELECT
SELECT
JSONB_AGG(
JSONB_BUILD_OBJECT(
'membershipId', membership_id::text,
Expand All @@ -34,11 +34,11 @@
'isPrivate', is_private,
'cheatLevel', cheat_level
)
ORDER BY instance_player.completed DESC, instance_player.time_played_seconds DESC
) as "players"
FROM instance_player
INNER JOIN player USING (membership_id)
WHERE instance_player.instance_id = team_pantheon_custom_race_leaderboard.instance_id
AND instance_player.completed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The JSONB_AGG for players can return NULL if all players in an entry are filtered out, but the Zod schema expects an array, causing a validation error.
Severity: HIGH

Suggested Fix

Wrap the JSONB_AGG(...) call in the SQL query with COALESCE(JSONB_AGG(...), '[]'::jsonb). This ensures that if no players match the filter, an empty array [] is returned instead of NULL, satisfying the Zod schema and preventing validation errors.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/services/leaderboard/team/custom.ts#L42

Potential issue: The SQL query filters players using `AND instance_player.completed`. If
a leaderboard entry contains only players who did not complete the activity, the
`JSONB_AGG` function will operate on an empty set and return `NULL`. However, the Zod
schema `zTeamLeaderboardEntry` defines the `players` field as a non-nullable array. When
the query result with a `NULL` `players` field is parsed, it will fail Zod validation,
resulting in an API error for requests involving such leaderboard entries. This is
likely for custom race leaderboards which may contain teams composed entirely of DNF
players.

Did we get this right? 👍 / 👎 to inform future reviews.

) as "lateral" ON true
WHERE position > $1 AND position <= ($1 + $2)
ORDER BY position ASC`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: A temporal inconsistency between deployment and a SQL migration causes searches for DNF players to return their team but omit them from the player list, breaking tests.
Severity: MEDIUM

Suggested Fix

The issue is caused by a temporary desynchronization between the search index and the query filter. The documented solution is to run the companion SQL migration immediately after API deployment to update the membership_ids column and remove DNF players, ensuring data consistency. Alternatively, modify the deployment process to prevent the API from being live until the migration is complete.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/services/leaderboard/team/custom.ts#L44

Potential issue: A temporal data inconsistency occurs between the API deployment and a
companion SQL migration. The `searchPantheonCustomRaceTeamLeaderboard` function can find
a team using a DNF player's ID from the `membership_ids` column, which is not yet
updated. However, the `getPantheonCustomRaceTeamLeaderboard` function then filters out
this player using the new `AND instance_player.completed` clause. This results in an API
response where a team is found for a player, but that player is missing from the
returned `players` array, causing the `assertTeamSearchIncludesMembership` test to fail.

Expand Down Expand Up @@ -71,12 +71,12 @@
)
if (!result) return null

const page = Math.ceil(result.position / take)
return {
page,
entries: await getPantheonCustomRaceTeamLeaderboard({
skip: (page - 1) * take,
take
})

Check warning on line 80 in src/services/leaderboard/team/custom.ts

View workflow job for this annotation

GitHub Actions / test

74-80 lines are not covered with tests
}
}
Loading