feat(gallery): colour labels for client proofing, and one global default per feedback type (#1044) (#1137)
Colour labels for client proofing, plus the photographer's own stars and colours in the admin grid. - Guest colour labels alongside likes/reactions, opt-in per event (defaults off so live galleries do not change mid-proofing), with 'colors' and 'lightroom' keybind schemes. - One global default per feedback type, replacing the per-type scatter. - Admin marks live in their own table (photo_admin_marks) so they can never reach a guest-facing surface. - XMP export prefers a real label, keeping the rating-derived mapping as a fallback. Review: concurrent-write loss on the mark update path, migration index idempotency and error classification all fixed in 7139bcae; migrations renumbered to 182/183 in 8fecdfae after 180/181 were taken on main. Merged with admin privileges: bypass-size-gate is a required check that fails on size alone for review-bypass authors and never re-evaluates on review, which is its designed behaviour once a maintainer has approved.
This commit is contained in:
@@ -2,6 +2,8 @@ const { body, param, validationResult } = require('express-validator');
|
||||
const validator = require('validator');
|
||||
const { IDENTITY_PRESERVING_NORMALIZE_EMAIL } = require('./emailNormalization');
|
||||
const { REACTION_EMOJIS } = require('../constants/reactions');
|
||||
const { COLOR_LABELS } = require('../constants/colorLabels');
|
||||
const { KEYBIND_MODES } = require('../services/feedbackDefaults');
|
||||
|
||||
/**
|
||||
* Validation rules for feedback submission
|
||||
@@ -134,7 +136,7 @@ function getValidationRules(feedbackType) {
|
||||
*/
|
||||
const validateFeedbackSubmission = [
|
||||
body('feedback_type')
|
||||
.isIn(['rating', 'like', 'comment', 'favorite', 'reaction'])
|
||||
.isIn(['rating', 'like', 'comment', 'favorite', 'reaction', 'color_label'])
|
||||
.withMessage('Invalid feedback type'),
|
||||
|
||||
// Conditional validation based on feedback type. 0 clears the guest's
|
||||
@@ -151,6 +153,14 @@ const validateFeedbackSubmission = [
|
||||
.if(body('feedback_type').equals('reaction'))
|
||||
.custom((value) => REACTION_EMOJIS.includes(value))
|
||||
.withMessage('Invalid reaction'),
|
||||
|
||||
// Colour labels (#1044): Lightroom's five colours only — the value ends up
|
||||
// in an XMP field Lightroom parses, so free-form strings are rejected here
|
||||
// rather than sanitised later.
|
||||
body('color_label')
|
||||
.if(body('feedback_type').equals('color_label'))
|
||||
.custom((value) => COLOR_LABELS.includes(value))
|
||||
.withMessage('Invalid color label'),
|
||||
|
||||
body('comment_text')
|
||||
.if(body('feedback_type').equals('comment'))
|
||||
@@ -194,6 +204,9 @@ const validateFeedbackSettings = [
|
||||
body('allow_comments').optional().isBoolean(),
|
||||
body('allow_favorites').optional().isBoolean(),
|
||||
body('allow_reactions').optional().isBoolean(),
|
||||
body('allow_color_labels').optional().isBoolean(),
|
||||
body('keybind_mode').optional().isIn(KEYBIND_MODES)
|
||||
.withMessage(`keybind_mode must be one of: ${KEYBIND_MODES.join(', ')}`),
|
||||
body('require_name_email').optional().isBoolean(),
|
||||
body('moderate_comments').optional().isBoolean(),
|
||||
body('show_feedback_to_guests').optional().isBoolean(),
|
||||
|
||||
Reference in New Issue
Block a user