feat(spec): unify conditional-visibility predicate under visibleWhen (ADR-0089)#2900
Open
os-zhuang wants to merge 3 commits into
Open
feat(spec): unify conditional-visibility predicate under visibleWhen (ADR-0089)#2900os-zhuang wants to merge 3 commits into
os-zhuang wants to merge 3 commits into
Conversation
…(ADR-0089) Make `visibleWhen` the single canonical conditional-visibility key across all layers (data field, view form section/field, page component), aligning with the existing `readonlyWhen` / `requiredWhen` family and the resolved `conditionalRequired → requiredWhen` precedent. D1 — canonical key: accept `visibleWhen` on `FormFieldSchema` / `FormSectionSchema` (view.zod.ts) and `PageComponentSchema` (page.zod.ts), documenting the per-layer binding root (runtime surfaces bind `record` + `current_user` + `page.<var>`; metadata-editing forms bind `data`). D2 — aliases + normalization: mark the view `visibleOn` and page `visibility` keys `@deprecated`; fold them into `visibleWhen` once at the schema boundary via a shared `normalizeVisibleWhen` zod `.transform()` (canonical wins when both are present), so no consumer re-implements the fallback. Codemod first-party sources to canonical `visibleWhen`: metadata-editing forms (`*.form.ts`), the showcase view/pages, and the affected tests + docs + the objectstack-formula skill + the expression-conformance ledger (both spellings kept as live CEL surfaces during the deprecation window). Out of scope, unchanged: boolean `visible` (Tab on/off), field `hidden`, gallery `visibleFields`, and unrelated `visibility` enums (feed / package / environment / agent). The `.strict()` flip (D3a), the lint rule (D3b), and the ObjectUI renderer reads (sibling repo) are staged follow-ups per the ADR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017fU25GeYSPKq9eEURsQffF
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 4 package(s): 103 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Regenerate the public API-surface snapshot to include the two new `@objectstack/spec` exports added by ADR-0089 — `normalizeVisibleWhen` and `VISIBILITY_ALIAS_KEYS` (shared visibility-normalization helper). Non-breaking (2 added, 0 removed/narrowed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017fU25GeYSPKq9eEURsQffF
This was referenced Jul 14, 2026
Add `validateVisibilityPredicates` (`@objectstack/lint`) and wire it into `os validate` + `os compile` as advisory warnings: - `visibility-alias-deprecated` — a deprecated `visibleOn` (view form) or `visibility` (page component) key in authored source → steer to `visibleWhen`. - `visibility-root-mislayered` — a runtime view/page visibility predicate rooted at `data.` (the metadata-editing-form root) → runtime surfaces bind `record`/`current_user`/`page.<var>`, so a `data.` root never matches. Runs on the PRE-parse (normalized) stack — like `validate-list-view-mode` — because the schema folds `visibleOn`/`visibility` into `visibleWhen` at parse, so the parsed stack no longer carries the alias the author wrote. Both rules are warnings; the build never fails on them. Addresses #2903 (ADR-0089 D3b). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017fU25GeYSPKq9eEURsQffF
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.
Implements ADR-0089 (
docs/adr/0089-unify-visibility-predicate-naming.md), closing the core of #2642.One concept — "show this only when the CEL predicate is TRUE" — was spelled three ways by layer (
visibleWhenon data fields,visibleOnon view forms,visibilityon page components), and zod's default strip made a mis-layered key vanish silently. This PR makesvisibleWhenthe single canonical key everywhere, aligning with the existingreadonlyWhen/requiredWhenfamily and the resolvedconditionalRequired → requiredWhenprecedent.What changed
D1 — canonical
visibleWhenis now accepted on view form sections/fields (FormFieldSchema,FormSectionSchemainview.zod.ts) and page components (PageComponentSchemainpage.zod.ts), matching the data-field semantics. The per-layer binding root is documented in TSDoc:*.view.ts,*.page.ts)record+current_user(pages also exposepage.<var>)*.form.ts)data— the row under editD2 — aliases + parse-time normalization.
visibleOn(view) andvisibility(page) are marked@deprecatedand folded intovisibleWhenonce, at the schema boundary, via a sharednormalizeVisibleWhenzod.transform()(packages/spec/src/shared/visibility.ts). Canonical wins when both are present; the alias is dropped from the parsed output. No renderer or validator re-implements the fallback.Codemod (first-party). Renamed in-scope usages to
visibleWhen: metadata-editing forms (field.form.ts,object.form.ts,page.form.ts,action.form.ts,report.form.ts,view.form.ts), the showcase view + pages, affected tests, docs (layout-dsl.mdx+ the layer→binding-root table,views.mdx,formulas.mdx), theobjectstack-formulaskill, and the expression-conformance ledger (both spellings kept as live CEL surfaces during the deprecation window).Tests
New
ADR-0089describe blocks inview.test.tsandpage.test.tsprove: deprecated alias →visibleWhennormalization, alias dropped from output, and canonical-wins-when-both-present. Verified green in isolation:@objectstack/spec(6721),example-showcase(55),objectql(842),metadata(260),rest(255), and the dogfood expression-conformance ledger. No first-party consumer reads the raw aliases.Out of scope / follow-ups (per the ADR's staged rollout)
.strict()flip and D3b — the@objectstack/lintrule: deferred; the ADR gates the strict flip on a full monorepo + example sweep and a deprecation window, and a broad strict flip has a large blast radius under parallel-agent development.visibleWhen): lives in the siblingobjectuirepo (not in this backend repo); companion change tracked with Implement ADR-0089: unify conditional-visibility predicate undervisibleWhen#2642.visible(Tab on/off), fieldhidden, galleryvisibleFields— unchanged per ADR-0089 D4.Includes a
minorchangeset with the FROM → TO migration mapping. ADR status flipped to Accepted.🤖 Generated with Claude Code
https://claude.ai/code/session_017fU25GeYSPKq9eEURsQffF
Generated by Claude Code