diff --git a/packages/backend/src/graphql/resolvers/playlists/queries.ts b/packages/backend/src/graphql/resolvers/playlists/queries.ts index c9c76268..84f3ba5a 100644 --- a/packages/backend/src/graphql/resolvers/playlists/queries.ts +++ b/packages/backend/src/graphql/resolvers/playlists/queries.ts @@ -274,6 +274,7 @@ export const playlistQueries = { layoutId: number; sizeId: number; setIds: string; + angle: number; page?: number; pageSize?: number; } }, @@ -364,9 +365,8 @@ export const playlistQueries = { tables.climbStats, and( eq(tables.climbStats.climbUuid, dbSchema.playlistClimbs.climbUuid), - // Only join stats when we have a specific angle to match - // Use playlist angle if set, otherwise use climb's default angle - eq(tables.climbStats.angle, sql`COALESCE(${dbSchema.playlistClimbs.angle}, ${tables.climbs.angle})`) + // Use the route angle (from input) to fetch stats for the current board angle + eq(tables.climbStats.angle, input.angle) ) ) .leftJoin( @@ -383,6 +383,7 @@ export const playlistQueries = { const trimmedResults = hasMore ? results.slice(0, pageSize) : results; // Transform results to Climb type + // Use the input angle (route angle) for consistent stats display const climbs: Climb[] = trimmedResults.map((result) => ({ uuid: result.uuid || result.climbUuid, layoutId: result.layoutId, @@ -390,7 +391,7 @@ export const playlistQueries = { name: result.name || '', description: result.description || '', frames: result.frames || '', - angle: result.angle ?? 0, + angle: input.angle, ascensionist_count: Number(result.ascensionist_count || 0), difficulty: result.difficulty || '', quality_average: result.quality_average?.toString() || '0', diff --git a/packages/backend/src/validation/schemas.ts b/packages/backend/src/validation/schemas.ts index 08c6b451..59fade7a 100644 --- a/packages/backend/src/validation/schemas.ts +++ b/packages/backend/src/validation/schemas.ts @@ -366,6 +366,7 @@ export const GetPlaylistClimbsInputSchema = z.object({ layoutId: z.number().int().positive(), sizeId: z.number().int().positive(), setIds: z.string().min(1), + angle: z.number().int(), page: z.number().int().min(0).optional(), pageSize: z.number().int().min(1).max(100).optional(), }); diff --git a/packages/shared-schema/src/schema.ts b/packages/shared-schema/src/schema.ts index 89d4ef5d..766a51fe 100644 --- a/packages/shared-schema/src/schema.ts +++ b/packages/shared-schema/src/schema.ts @@ -396,6 +396,7 @@ export const typeDefs = /* GraphQL */ ` layoutId: Int! sizeId: Int! setIds: String! + angle: Int! page: Int pageSize: Int } diff --git a/packages/web/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/playlist/[playlist_uuid]/playlist-climbs-list.tsx b/packages/web/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/playlist/[playlist_uuid]/playlist-climbs-list.tsx index 2a86401f..f4497800 100644 --- a/packages/web/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/playlist/[playlist_uuid]/playlist-climbs-list.tsx +++ b/packages/web/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/playlist/[playlist_uuid]/playlist-climbs-list.tsx @@ -70,6 +70,7 @@ export default function PlaylistClimbsList({ layoutId: boardDetails.layout_id, sizeId: boardDetails.size_id, setIds: boardDetails.set_ids.join(','), + angle: angle, page: pageParam, pageSize: 20, }, diff --git a/packages/web/app/lib/graphql/operations/playlists.ts b/packages/web/app/lib/graphql/operations/playlists.ts index dc5384b8..712bf02a 100644 --- a/packages/web/app/lib/graphql/operations/playlists.ts +++ b/packages/web/app/lib/graphql/operations/playlists.ts @@ -255,6 +255,7 @@ export interface GetPlaylistClimbsInput { layoutId: number; sizeId: number; setIds: string; + angle: number; page?: number; pageSize?: number; }