fix(api): enum validation messages (#363) + booking-requests guardrail - #364
Merged
telivity-otaip merged 2 commits intoSep 9, 2026
Merged
Conversation
Post a folio charge with type "beverage" and the API answers
type must be one of the following values:
with nothing after the colon. The caller is told they are wrong and never
told what right looks like.
class-validator's IsEnum is for TypeScript enum objects. It validates with
Object.keys(entity).map(k => entity[k]), which happens to read an array's
values, so the check works; but it builds its message from
Object.entries(entity).filter(([k]) => isNaN(parseInt(k))), which drops every
key of an array because array keys are all numeric. So the allowed-value list
comes out empty. IsIn is the decorator for a list of allowed values, and
interpolates it.
Every enum decorator in the API was affected: 88 across 64 files, covering
accounting, folio, payment, reservation, rate plan, housekeeping, media,
groups, waitlist and the booking-requests package.
Validation behaviour does not change. Both decorators compare the same value
against the same list.
apps/api/src/validation-messages.spec.ts reads class-validator's metadata
registry rather than the source, so it covers the copies PartialType and
OmitType generate, which no grep sees. It asserts a rendered message too, and
that is what caught the first version of the metadata assertion: it filtered
on `type`, which is 'customValidation' for every ValidateBy decorator, so it
matched nothing and passed with an @IsEnum deliberately planted.
Maintainer hygiene on #363: the metadata registry check only loaded apps/api modules/**/dto, so a future @IsEnum([...]) in packages/booking-requests could regress unnoticed. Eager-load those HTTP DTOs too and assert ListBookingRequestsDto registers. Co-authored-by: telivity-otaip <telivity-otaip@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Charles’s #363 in full, plus one maintainer hygiene commit we could not push to his fork (
telivity-otaip/cursor[bot]both 403 onmodernit-com-au/haipeven with “allow edits from maintainers”).His work:
@IsEnum([...])→@IsIn([...])so 400s name the allowed values. Guardrail spec on class-validator metadata.Hygiene (1cc3595): eager-load
packages/booking-requests/src/http/dto/**in that spec so a future@IsEnumthere cannot sneak past.Merge this and close #363 as superseded, or merge #363 as-is and ignore this. Full credit to @modernitconsultants .