fix(feedback): persist guest feedback settings, unshadow the guest route (#1030) (#1032)

Enabling Guest Feedback on an event could silently do nothing.

1. `updateEventFeedbackSettings` spread the request body straight into the
   knex UPDATE. The admin event form posts its whole client-side state,
   including three keys that were never columns on event_feedback_settings
   (`enable_rate_limiting`, `rate_limit_window_minutes`,
   `rate_limit_max_requests`), so the write threw and the route answered 500.
   Writable columns are now whitelisted; identity columns and timestamps stay
   server-managed.

2. EventDetailsPage swallowed that 500 in a bare `catch {}` ("Error already
   handled by mutation" — it is a different request), so the admin was left
   looking at "Event updated successfully" while the toggle never persisted.
   The error is surfaced now and the settings query is invalidated on success.

3. gallery.js declared a duplicate `GET /:slug/feedback-settings`. server.js
   mounts galleryRoutes before galleryFeedback, so it shadowed the real
   handler and dropped the per-guest caps (#655) from the guest payload — the
   gallery could never render the favorite/like limits or their counters.

Timestamps are written as ISO strings so they round-trip on both engines.

Claude-Session: https://claude.ai/code/session_0168gubtwYYacJv8weAjy8DM

Co-authored-by: Paul Nothaft <[email protected]>
This commit is contained in:
Paul Nothaft
2026-08-13 18:51:16 +02:00
committed by GitHub
co-authored by Paul Nothaft
parent 8b6cd3c74f
commit de459c701f
4 changed files with 219 additions and 32 deletions
+5 -20
View File
@@ -1890,26 +1890,11 @@ router.get('/:slug/preview/:photoId',
}
);
// Get feedback settings for gallery
router.get('/:slug/feedback-settings', verifyGalleryAccess, async (req, res) => {
try {
const feedbackService = require('../services/feedbackService');
const settings = await feedbackService.getEventFeedbackSettings(req.event.id);
res.json({
feedback_enabled: settings.feedback_enabled || false,
allow_ratings: settings.allow_ratings,
allow_likes: settings.allow_likes,
allow_comments: settings.allow_comments,
allow_favorites: settings.allow_favorites,
show_feedback_to_guests: settings.show_feedback_to_guests,
require_name_email: settings.require_name_email || false,
identity_mode: settings.identity_mode || 'simple'
});
} catch (error) {
errorResponse(res, error, 500, 'Failed to fetch feedback settings');
}
});
// GET /:slug/feedback-settings lives in galleryFeedback.js. A duplicate of it
// used to sit here, and since server.js mounts galleryRoutes before
// galleryFeedback it shadowed the real handler — dropping the per-guest caps
// (#655) from the guest payload, so the gallery could never render the
// favorite/like limits or their counters (#1030).
// Get photo stats
router.get('/:slug/stats', verifyGalleryAccess, async (req, res) => {