fix(view): the spec→FilterBuilder map follows the four operators #2942 added - #3022
Merged
Merged
Conversation
…added CANONICAL_TO_BUILDER mapped starts_with, ends_with, is_null and is_not_null to null, with a comment asserting the FilterBuilder had no such operator. #2942 gave it startsWith/endsWith/isNull/isNotNull and this table did not follow — so a stored view carrying any of the four still reached the builder as a raw spelling it could by then have rendered, and the comment was false. is_null/is_not_null map to isNull/isNotNull, NOT isEmpty/isNotEmpty: the builder draws both pairs now, and folding the NULL predicate onto the empty-string one would rewrite the author's operator on the next save. The old guard could not catch this — it compared the unmapped set against a hand-kept gap list, and neither side moves when the BUILDER gains an operator. The new assertion is derived: starts_with and startsWith fold to the same key, so an unmapped canonical operator whose folded name matches a folded builder id is an omission by definition. Confirmed by reverting the four mappings, which reproduces the drift as four named failures. The unmapped set is now empty — all 19 canonical members translate. Refs #2945, #2942, #2989 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
This was referenced Jul 30, 2026
Closed
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.
Found while implementing objectstack-ai/objectstack#4135 — a concurrent change made a table I added in #2989 quietly wrong.
The drift
CANONICAL_TO_BUILDER(view-config-utils.ts) mapped four canonicalVIEW_FILTER_OPERATORSmembers tonull, with a comment asserting the reason:The first half stopped being true. #2942 added
startsWith,endsWith,isNullandisNotNullto the FilterBuilder — its own comment says they "validated at the data layer but were unreachable from this dropdown". This table did not follow, so a stored view carrying any of the four still reached the builder as a raw spelling it could by then have rendered, and the comment explaining why was simply false.All four now map.
is_null/is_not_null→isNull/isNotNull, notisEmpty/isNotEmpty: the builder draws both pairs now, so folding the NULL predicate onto the empty-string one would silently rewrite the author's operator the next time the view was saved. The unmapped set is empty — all 19 canonical members translate.The guard could not have caught this. Now it can.
The parity test asserted that the unmapped set equalled a hand-kept list of gaps. That comparison stays true when the builder gains an operator, because neither side of it moves — the exact drift that happened.
The new assertion is derived rather than hand-kept:
starts_withandstartsWithfold to the same key, so an unmapped canonical operator whose folded name matches a folded builder id is an omission by definition — no list to remember.Confirmed it has teeth rather than trusting the green. Reverting the four mappings to
nullreproduces the original drift as four named failures:Also added an explicit assertion that the NULL and empty-string pairs stay distinct, since that is the one mapping a future edit might be tempted to collapse.
Verification
plugin-view: 72 tests across 4 files, green (12 in the parity guard, up from 9).Note on scope
This is the same public-API surface as #2989 —
toFilterGrouphas no in-repo caller — so no in-repo behaviour changes. It is worth fixing because the table is the third of the three the #2901 audit identified, and because a guard that cannot detect a whole class of drift is worse than one that says so.Refs #2945, #2942, #2989
🤖 Generated with Claude Code