fix(feedback): align word-filter severity vocabulary with the admin UI

WordFilterManager.tsx sends low/moderate/high/block; the validator only
accepted mild/moderate/severe, so 3 of the 4 UI levels 400'd with "Invalid
severity level" -- including "block", the strongest advertised tier.

Aligning isIn() alone would have made "block" accepted but semantically
inert: feedbackModeration.js branches on 'severe'/'moderate', so "block"
would fall through to the flag-only branch and behave as the weakest level.
Map the UI vocabulary onto the existing outcomes instead, per the legend the
UI itself renders: block -> reject, moderate/high -> needs approval,
low -> flag only.

'severe' stays an accepted alias in the blocking predicate so any row written
through the old validator (the field is optional, so a direct API caller
could have stored one) keeps blocking. No data migration needed: the column
is a bare varchar(20) default 'moderate' with no CHECK, no enum and no seed
rows, and 'mild' already lands in the flag-only branch that 'low' now means.

Refs testplan REPORT.md #2 (Part 3, J.11).
This commit is contained in:
Paul Nothaft
2026-09-01 16:23:22 +02:00
parent e18ab0d842
commit 6f7aa59fad
3 changed files with 83 additions and 8 deletions
+1 -1
View File
@@ -241,7 +241,7 @@ const validateWordFilter = [
.withMessage('Word must be between 2 and 100 characters'),
body('severity')
.optional()
.isIn(['mild', 'moderate', 'severe'])
.isIn(['low', 'moderate', 'high', 'block'])
.withMessage('Invalid severity level')
];