diff --git a/src/collections/EventOccurrences.ts b/src/collections/EventOccurrences.ts index 5c98d2b..0f48199 100644 --- a/src/collections/EventOccurrences.ts +++ b/src/collections/EventOccurrences.ts @@ -1,6 +1,7 @@ import { CollectionConfig } from 'payload' import { isAdminOrEmployee } from '@/collections/access/admin' import { canMutateOccurrenceOfAssignedEvent } from '@/collections/access/assigned' +import { revalidateTagHook } from '@/utils/revalidate' export const EventOccurrences: CollectionConfig = { slug: 'eventOccurrence', @@ -91,4 +92,8 @@ export const EventOccurrences: CollectionConfig = { update: canMutateOccurrenceOfAssignedEvent(), delete: isAdminOrEmployee(), }, + hooks: { + afterChange: [revalidateTagHook('events')], + afterDelete: [revalidateTagHook('events')], + }, } diff --git a/src/collections/Events.ts b/src/collections/Events.ts index a7471c5..c1c116c 100644 --- a/src/collections/Events.ts +++ b/src/collections/Events.ts @@ -12,6 +12,7 @@ import { unassignedAdditions, } from '@/collections/access/assigned' import { regenerateOccurrencesForEvent } from '@/jobs/generateEventOccurrences' +import { revalidateTagHook } from '@/utils/revalidate' export const Events: CollectionConfig = { slug: 'event', @@ -431,6 +432,8 @@ export const Events: CollectionConfig = { ) } }, + + revalidateTagHook('events'), ], beforeDelete: [ async ({ id, req }) => { diff --git a/src/collections/Worship.ts b/src/collections/Worship.ts index b92c871..5ff8720 100644 --- a/src/collections/Worship.ts +++ b/src/collections/Worship.ts @@ -1,4 +1,5 @@ import { CollectionConfig } from 'payload' +import { revalidateTagHook } from '@/utils/revalidate' import { canCreateAssignedWorship, canMutateAssignedWorship, @@ -151,4 +152,8 @@ export const Worship: CollectionConfig = { update: canMutateAssignedWorship(), delete: canMutateAssignedWorship(), }, + hooks: { + afterChange: [revalidateTagHook('worship')], + afterDelete: [revalidateTagHook('worship')], + }, } diff --git a/src/fetch/eventOccurrences.ts b/src/fetch/eventOccurrences.ts index 89cef8b..be9174e 100644 --- a/src/fetch/eventOccurrences.ts +++ b/src/fetch/eventOccurrences.ts @@ -80,7 +80,7 @@ const getUpcomingOccurrences = unstable_cache( }) as Promise> }, ['fetchUpcomingOccurrences'], - { revalidate: CACHE_TTL }, + { tags: ['events'], revalidate: CACHE_TTL }, ) export async function fetchUpcomingOccurrences( @@ -146,7 +146,7 @@ const getPastOccurrences = unstable_cache( }) as Promise> }, ['fetchPastOccurrences'], - { revalidate: CACHE_TTL }, + { tags: ['events'], revalidate: CACHE_TTL }, ) export async function fetchPastOccurrences( diff --git a/src/fetch/worship.ts b/src/fetch/worship.ts index be01aa9..8bce318 100644 --- a/src/fetch/worship.ts +++ b/src/fetch/worship.ts @@ -71,7 +71,7 @@ const getWorship = unstable_cache( }) as Promise> }, ['fetchWorship'], - { revalidate: CACHE_TTL }, + { tags: ['worship'], revalidate: CACHE_TTL }, ) export const fetchWorship = async ( diff --git a/src/utils/revalidate.ts b/src/utils/revalidate.ts new file mode 100644 index 0000000..91f6a55 --- /dev/null +++ b/src/utils/revalidate.ts @@ -0,0 +1,16 @@ +import { revalidateTag } from 'next/cache' + +/** + * Returns a Payload hook that invalidates a Next cache tag. + * + * Safe to use for docs created/deleted programmatically (e.g. by + * regenerateMassesForChurch / regenerateOccurrencesForEvent), since the + * Local API runs collection hooks. The jobs queue can execute outside a + * Next request scope where revalidateTag throws — swallow that; the + * fetch-side TTL covers the gap there. + */ +export const revalidateTagHook = (tag: string) => () => { + try { + revalidateTag(tag) + } catch {} +}