Repository navigation
docs(guide): author object-grid filter in the canonical array form - #7973
Merged
baozhoutao merged 1 commit intoSep 6, 2026
Merged
Conversation
`objectos-integration.mdx` authored `object-grid.filter` as an `and:`-keyed
object of `{ field, operator, value }` entries. No reader lowers that shape:
`toFilterNode` recognises a `ViewFilterRule[]`, an AST node array and a
MongoDB-style record, so a record whose value is an array takes
`convertFiltersToAST`'s simple-equality branch and becomes
`['and', '=', [...]]` — which `isFilterAST` accepts and the engine evaluates
as a comparison on a field literally named `and`. Wrong rows, silently.
The grid's own registry entry is the authority: `filter` is registered
`type: 'array'` and described as "the canonical spelling"
(`packages/plugin-grid/src/index.tsx`), `ObjectGridSchema.filter?: any[]`
declares the same, and `packages/plugin-grid/README.md` shows the array form
twice. The two entries are AND-ed implicitly, so the example now authors the
array directly.
`eq` / `gte` were also swapped for the canonical `equals` /
`greater_than_or_equal`: both were only members of
`VIEW_FILTER_OPERATOR_ALIASES`, the spec's deprecated migration bridge, whose
own doc comment says new producers must emit the canonical forms. The
lowering is identical either way, so this changes nothing at runtime and
stops the page teaching a spelling that may be dropped in a future major.
The comment above the key no longer says "ObjectQL filter syntax": this is
the grid's JSON-rules filter, not ObjectQL filter syntax.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
baozhoutao
marked this pull request as ready for review
September 6, 2026 05:12
baozhoutao
deleted the
claude/issue-7713-objectos-integration-filter-array-form
branch
September 6, 2026 05:31
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.
Fixes #7713
content/docs/guide/objectos-integration.mdxauthoredobject-grid.filteras anand:-keyed object of{ field, operator, value }entries. It now authors the registry's canonical array, the two entries AND-ed implicitly, and the comment above the key says what the key actually is.One file, 7 insertions, 7 deletions. No
packages/**change: adding anand/$andbranch toconvertFiltersToASTis objectui#6948's card, not this one.The declared type of
filter, and why the gate was green on the wrong shapeMeasured on this branch:
packages/plugin-grid/src/index.tsx:218registers{ name: 'filter', type: 'array', ... 'Filter criteria in JSON-rules form. The canonical spelling ...' }.packages/types/src/objectql.ts:679, onObjectGridSchema:filter?: any[];(doc comment: "Array-based filter configuration"). The array form is the DECLARED form, not only the registry's.packages/plugin-grid/README.md:468and:529already show the array form, both underconst schema: ObjectGridSchema = { ... }.check:doc-snippetswas green on the object form for one reason, and it is not coverage: the example's literal is a bareconst schema = { ... }with no type annotation, soObjectGridSchema.filter?: any[]was never consulted. Two controls, both run on this tree and both restored byte-identically:dataSource: zzzUndefinedIdent,at:278turned the gate RED —content/docs/guide/objectos-integration.mdx:278:15 TS2304: Cannot find name 'zzzUndefinedIdent'./Semantic phase: 477 of 477 block(s) judged, 1 failed.Green was never "not covered".import type { ObjectGridSchema } from '@object-ui/types';and annotating the literal, with the pre-fixand:object still in place, turned the gate RED with exactly one diagnostic:content/docs/guide/objectos-integration.mdx:282:5 TS2353: Object literal may only specify known properties, and 'and' does not exist in type 'any[]'.Control 2 is not applied here — annotating the literal is outside this card's scope fence (the fence is the
filtervalue and the comment above it). It is filed as objectui#7972, same class as objectui#7778.Operator vocabulary:
eq/gtewere deprecated aliases, not membersThe card's prescription named only the array shape, so the operator spelling was measured separately, against the shipped
@objectstack/spec:Neither
eqnorgteis a member; both live only inVIEW_FILTER_OPERATOR_ALIASES, whose own doc comment reads: "Deprecated: new producers MUST emit the canonical forms; these aliases are a migration bridge and may be dropped in a future major."packages/plugin-grid/README.md— the tree's own authority for this key — already spells the canonicalequals/after.The lowering is byte-identical either way (
viewFilterRuleToNodenormalises first), so this changes nothing at runtime. Along the four decision axes: real need — a doc example is a producer, and every copy of it emits the deprecated spelling; long-term — contract-first, one vocabulary rather than N dialects, which is the alias table's own stated purpose; AI-error prevention — teaching the alias is exactly the tolerance-hides-mistakes shape, since the fold is silent and the author never learns the canonical name; startup focus, no gradualism — the maintainer's 2026-08-27 ruling retires deprecated spellings immediately rather than in stages, and there is no named external user of the alias in the docs. All four point the same way, so there is no trade-off to hand up.Ablation, reported as observed (no red/green pin is owed here)
On the committed tree, the
and:-keyed object was put back — the mutated file hashed to3115b38eafb92ccf8ba1ba15b138668a61eea3f8, which isorigin/main's own blob for this page, so the mutation provably reproduced the pre-fix bytes exactly. With it in place:The gate stays GREEN on the defect. That is the finding's point: no reader in this repository refuses this shape. Restore leg:
git checkout HEAD -- ..., blob back to1db05a62866e59329427841aaf020f10da81ad6d,git diff HEADempty. Marker observation on disk: the canonical-array marker counted 1 before the mutation, 0 after it, 1 after the restore.This PR owes no new red/green pin. The docs-only fix has no runtime face, and the mechanism gap (
convertFiltersToASThas noandbranch) is objectui#6948's card. What this PR can honestly claim is that the page no longer teaches a shape no reader lowers; it cannot claim anything now stops the shape coming back — objectui#7972 is that repair.Verification (all redirect-then-capture; each line is the gate's own verdict)
Dependency closure built first through the shared lock (
os-verify-lock: VERDICT command-exit 0,34 successful, 34 total), using this gate's own--build-filterclosure.check:doc-snippetsSemantic phase: 477 of 477 block(s) judged, 0 failed./Every covered documentation snippet compiles against the built types.check:doc-types✅ Every documented component type is registered.(188 files, 889typeliterals)check:doc-fences✅ check:doc-fences — every TypeScript block in 227 document(s) is fenced ts/tsx/typescript ...check-doc-linksLinks are valid across 17 scan roots.check:control-bytes✅ check-control-bytes: OK (scanned 6417 tracked text file(s); skipped 85 binary).check:docs-route-closurecontent/docs)check-changeset-presence✅ No source or published contract of a released package changed in this range, so no changeset is owed.— followed literally, so no.changeset/*.mdis addedcheck-governed-queue-guard --test content/docs/guide/objectos-integration.mdx✅ NOT GOVERNED — 1 path(s) checked against 5 governed surface(s); none matched.Ran on the final commit
8b363fe41. Plus a self-scan for control bytes on the changed file:grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'returned no matches.Not run, and declared rather than skipped:
check:doc-example-readersreads JSDoc@exampleblocks inpackages/*/src/**, a surface this diff does not touch; repo-widepnpm lintis CI's run.The page is NOT a governed surface (the guard's verdict above), so no maintainer-brief section is owed. This PR stays draft regardless — the dispatch fences it that way.
Out of scope, filed unassigned
content/docs/fields/lookup.mdx:43andcontent/docs/fields/user.mdx:43authorlookupFilterswith the same deprecated aliases (eq,ne). Different pages, different key: not touched here.const schema = {literals across 12 doc pages, against 20 annotated across 9.Measured and deliberately left alone:
and: [occurs exactly once undercontent/docsonorigin/main— the instance this PR fixes. The// ObjectQL sortingcomment two lines below is untouched (it describessort, outside the fence), and$filter: { status: 'active' }at:306is a MongoDB-style record, which IS one of the three shapestoFilterNodelowers.Generated by Claude Code