Replace N separate GET_PLAYLISTS_FOR_CLIMB GraphQL requests with a single
batched playlistMembershipsForClimbs query. This adds:
- New GraphQL query, input type, and return type in shared schema
- Backend resolver using a single SQL query with inArray for batch lookup
- Validation schema for the batch input (max 200 UUIDs)
- Client-side operation and TypeScript types
Also fixes stale closure risk in addToPlaylist/removeFromPlaylist callbacks
by creating new Sets instead of mutating existing ones in-place, and
refactors the playlists fetch from useEffect+useState to useQuery for
consistency with the rest of the hook and automatic caching/deduplication.
https://claude.ai/code/session_013FeKjWGrgDj3N2oq9kvU6R
Summary
Refactored playlist data fetching to use React Query for state management and introduced a new batched GraphQL query to fetch playlist memberships for multiple climbs in a single request, replacing N separate queries with one optimized call.
Key Changes
Frontend (packages/web/app/hooks/use-climb-actions-data.tsx):
useStatehooks forplaylists,playlistMemberships, andplaylistsLoadinguseQueryfor both user playlists and playlist memberships, providing automatic caching and consistencyplaylistsForClimbqueries with a single batchedGET_PLAYLIST_MEMBERSHIPS_FOR_CLIMBSqueryqueryClient.setQueryData()instead of state settersrefreshPlaylists()to usequeryClient.invalidateQueries()Backend (packages/backend/src/graphql/resolvers/playlists/queries.ts):
playlistMembershipsForClimbsresolver that accepts multiple climb UUIDsGraphQL Schema (packages/shared-schema/src/schema.ts):
GetPlaylistMembershipsForClimbsInputinput type for batch requestsPlaylistMembershipEntrytype to represent climb-to-playlists mappingplaylistMembershipsForClimbsquery field to the Query typeGraphQL Operations (packages/web/app/lib/graphql/operations/playlists.ts):
GET_PLAYLIST_MEMBERSHIPS_FOR_CLIMBSquery definitionValidation (packages/backend/src/validation/schemas.ts):
GetPlaylistMembershipsForClimbsInputSchemawith validation for board type, layout ID, and climb UUIDs (max 200)Notable Implementation Details
https://claude.ai/code/session_013FeKjWGrgDj3N2oq9kvU6R