From 596ec71191947534ab8686270df72bd3bcdef188 Mon Sep 17 00:00:00 2001 From: Michilis Date: Sat, 7 Mar 2026 19:36:12 +0000 Subject: [PATCH] Fix stale social media preview: revalidate next-event fetch, reject past featured events Made-with: Cursor --- backend/src/routes/site-settings.ts | 9 ++++++++- frontend/.env.example | 3 +++ frontend/src/app/(public)/page.tsx | 4 +++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/backend/src/routes/site-settings.ts b/backend/src/routes/site-settings.ts index db35dc6..5ff0592 100644 --- a/backend/src/routes/site-settings.ts +++ b/backend/src/routes/site-settings.ts @@ -200,8 +200,15 @@ siteSettingsRouter.put('/featured-event', requireAuth(['admin']), zValidator('js if (event.status !== 'published') { return c.json({ error: 'Event must be published to be featured' }, 400); } + const eventEndTime = event.endDatetime || event.startDatetime; + if (new Date(eventEndTime).getTime() <= Date.now()) { + return c.json( + { error: 'Cannot feature an event that has already ended' }, + 400 + ); + } } - + // Get or create settings const existing = await dbGet( (db as any).select().from(siteSettings).limit(1) diff --git a/frontend/.env.example b/frontend/.env.example index 73dc506..c7d9259 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -25,6 +25,9 @@ NEXT_PUBLIC_TIKTOK=spanglishsocialpy # Must match the REVALIDATE_SECRET in backend/.env REVALIDATE_SECRET=change-me-to-a-random-secret +# Next event cache revalidation (seconds) - homepage metadata/social preview refresh interval. Default: 3600 +NEXT_EVENT_REVALIDATE_SECONDS=3600 + # Plausible Analytics (optional - leave empty to disable tracking) NEXT_PUBLIC_PLAUSIBLE_URL=https://analytics.azzamo.net NEXT_PUBLIC_PLAUSIBLE_DOMAIN=spanglishcommunity.com diff --git a/frontend/src/app/(public)/page.tsx b/frontend/src/app/(public)/page.tsx index e6a7283..ed4e23e 100644 --- a/frontend/src/app/(public)/page.tsx +++ b/frontend/src/app/(public)/page.tsx @@ -38,8 +38,10 @@ interface NextEvent { async function getNextUpcomingEvent(): Promise { try { + const revalidateSeconds = + parseInt(process.env.NEXT_EVENT_REVALIDATE_SECONDS || '3600', 10) || 3600; const response = await fetch(`${apiUrl}/api/events/next/upcoming`, { - next: { tags: ['next-event'] }, + next: { tags: ['next-event'], revalidate: revalidateSeconds }, }); if (!response.ok) return null; const data = await response.json();