feat: auto-update sitemap when events are added/updated/removed

- Use tag-based cache for sitemap event list (events-sitemap)
- Add POST /api/revalidate endpoint (secret-protected) to trigger revalidation
- Backend calls revalidation after event create/update/delete
- Add REVALIDATE_SECRET to .env.example (frontend + backend)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Michilis
2026-02-12 03:51:00 +00:00
parent 74464b0a7a
commit af94c99fd2
5 changed files with 67 additions and 1 deletions

View File

@@ -15,6 +15,28 @@ interface UserContext {
const eventsRouter = new Hono<{ Variables: { user: UserContext } }>();
// Trigger frontend sitemap revalidation (fire-and-forget)
function revalidateSitemap() {
const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3002';
const secret = process.env.REVALIDATE_SECRET;
if (!secret) {
console.warn('REVALIDATE_SECRET not set, skipping sitemap revalidation');
return;
}
fetch(`${frontendUrl}/api/revalidate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ secret, tag: 'events-sitemap' }),
})
.then((res) => {
if (!res.ok) console.error('Sitemap revalidation failed:', res.status);
else console.log('Sitemap revalidation triggered');
})
.catch((err) => {
console.error('Sitemap revalidation error:', err.message);
});
}
// Helper to normalize event data for API response
// PostgreSQL decimal returns strings, booleans are stored as integers
function normalizeEvent(event: any) {
@@ -337,6 +359,9 @@ eventsRouter.post('/', requireAuth(['admin', 'organizer']), zValidator('json', c
await (db as any).insert(events).values(newEvent);
// Revalidate sitemap when a new event is created
revalidateSitemap();
// Return normalized event data
return c.json({ event: normalizeEvent(newEvent) }, 201);
});
@@ -373,6 +398,9 @@ eventsRouter.put('/:id', requireAuth(['admin', 'organizer']), zValidator('json',
(db as any).select().from(events).where(eq((events as any).id, id))
);
// Revalidate sitemap when an event is updated (status/dates may have changed)
revalidateSitemap();
return c.json({ event: normalizeEvent(updated) });
});
@@ -429,6 +457,9 @@ eventsRouter.delete('/:id', requireAuth(['admin']), async (c) => {
// Finally delete the event
await (db as any).delete(events).where(eq((events as any).id, id));
// Revalidate sitemap when an event is deleted
revalidateSitemap();
return c.json({ message: 'Event deleted successfully' });
});