fix(festivals): scope query cache keys by all filter#113
Conversation
…s and editions
Encode the 'all' parameter into query cache keys to prevent collisions:
- festivalsKeys.all() now includes { all: boolean } in the key
- editionsKeys.all() now includes { all: boolean } in the key
- Separate cache entries for published-only vs include-unpublished queries
Update mutations to use prefix-based invalidation (queryKey: ['festivals'])
so all related queries refresh regardless of their 'all' parameter value.
This ensures both public and admin views get correct, non-stale data.
Fixes #55
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…tion
- { all: !!all } simplified to { all } — real call sites never pass
an explicit false, so the normalization added no value.
- Create mutations invalidate via festivalsKeys.all()/editionsKeys.all()
instead of the broad ["festivals"] prefix: a brand-new resource has
no existing item()/bySlug() cache entry to bust, so the narrower key
is sufficient. Update/delete mutations keep the broad prefix since
they do need to invalidate an existing resource's item/bySlug cache.
festivalsKeys.root()/editionsKeys.root(festivalId) are now the single source for the "festivals"/"festivals",festivalId,"editions" prefix; all/item/bySlug build from them. Mutations invalidate via root() instead of hardcoded literal arrays. Threads festivalId through the edition update/delete mutations (was missing from their variables) so editionsKeys.root(festivalId) can scope invalidation to the correct festival instead of matching every festival's editions.
There was a problem hiding this comment.
Pull request overview
This PR updates TanStack Query cache key factories for festivals and festival editions so the all filter (published-only vs include-unpublished) is encoded into list query keys, preventing public/admin cache collisions while keeping mutation invalidation broad.
Changes:
- Scoped festivals list query keys by
alland introduced afestivalsKeys.root()prefix for broad invalidation. - Scoped editions list query keys by
all, introducededitionsKeys.root(festivalId), and added abySlugRoot()for consistent invalidation. - Updated admin flows and edition update/delete mutations to pass
festivalIdand invalidate edition caches by festival root.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/admin/festivals/ScheduleRevealControl.tsx | Passes festivalId through to edition update mutation variables. |
| src/pages/admin/festivals/FestivalEditionManagement.tsx | Includes festivalId in edition update/delete mutation calls. |
| src/pages/admin/festivals/FestivalEdition.tsx | Supplies festivalId prop to schedule reveal control. |
| src/api/festivals/useUpdateFestival.ts | Switches invalidation to festivalsKeys.root() for broad refresh. |
| src/api/festivals/useFestivals.ts | Uses festivalsKeys.all({ all }) for filter-scoped list caching. |
| src/api/festivals/useDeleteFestival.ts | Switches invalidation to festivalsKeys.root() for broad refresh. |
| src/api/festivals/types.ts | Adds root() and makes list keys include { all }. |
| src/api/editions/useUpdateFestivalEdition.ts | Requires festivalId for root invalidation; invalidates bySlugRoot(). |
| src/api/editions/useFestivalEditionsForFestival.ts | Uses editionsKeys.all(festivalId, { all }) for filter-scoped list caching. |
| src/api/editions/useDeleteFestivalEdition.ts | Updates mutation variables + invalidates editions by festival root and bySlugRoot(). |
| src/api/editions/useCreateFestivalEdition.ts | Adds editions key usage for invalidation (currently too specific; see comments). |
| src/api/editions/types.ts | Adds root(), scopes list keys by { all }, adds bySlugRoot(). |
festivalsKeys.all()/editionsKeys.all() now encode { all: undefined },
which doesn't partial-match the admin's cached { all: true } variant
in TanStack Query's key matching, so creating a festival/edition
silently failed to refresh the admin table. root() has no all-filter
segment to mismatch on, so it correctly invalidates both variants.
…eys.root() editionsKeys.bySlug now nests under festivalsKeys.root() instead of a separate "festival-editions" top-level segment, so one festivalsKeys.root() invalidation covers festivals, editions (by id and by slug) in a single call. Drops the now-unnecessary festivalId threading through the edition update/delete mutations and their call sites, since the broad root() invalidation no longer needs it.
Encodes the
allfilter into festivals/editions query keys so published-only and admin (unpublished-included) variants no longer share one cache entry. Mutations still invalidate the broad prefix so both variants refresh. Closes #55.Verification
Generated by Claude Code