Skip to content

Unify hand-written @object-ui/types zod with @objectstack/spec/ui (ListViewSchema drift) #2231

Description

@os-zhuang

Problem

@object-ui/types ships a hand-written copy of the ObjectQL/UI zod schemas (packages/types/src/zod/objectql.zod.ts, header: "Following @objectstack/spec UI specification format" — not generated). The authoritative schemas live in framework @objectstack/spec (src/ui/view.zod.ts etc.), which @object-ui/types already depends on (@objectstack/spec ^11.7.0) and already imports at runtime for stack-level schemas (ObjectStackSchema, defineStack, … — see packages/types/src/index.ts).

So the same concept is defined twice, in parallel, and the two copies have drifted hard.

Evidence — ListViewSchema field drift

Top-level field-name diff (spec 55 vs objectui 79):

  • Only in spec: appearance, bulkActionDefs, calendar, chart, columns, compactToolbar, data, description, fieldOrder, filter, gallery, gantt, grouping, kanban, name, order, performance, responsive, rowColor, tabs, timeline, tree, userActions
  • Only in objectui: fields, filters, viewType, objectName, showSearch, showSort, showFilters, showGroup, showHideFields, showColor, showDensity, densityMode, clickIntoRecordDetails, addRecordViaForm, addDeleteRecordsInline, … (plus nested-field noise from conditionalFormatting/exportOptions/pagination/addRecord)

These aren't cosmetic — the two use different vocabularies (spec columns/filter/grouping; objectui fields/filters/viewType + a show* flag family).

Why it matters

  • Double maintenance + silent divergence. Any schema change has to be mirrored by hand, and nothing enforces the copies stay in sync. Concrete example: the ADR-0053 phase-4 guardrail just landed in the spec (framework PR feat(spec,lint): reject userFilters on object list views (ADR-0053 phase 4) framework#2583) and would have to be re-applied here by hand.
  • Behavioural inconsistency. A payload valid under one copy may be stripped/rejected differently under the other.

Proposed direction

Replace the hand-written UI zod in @object-ui/types with imports from @objectstack/spec/ui (the spec already exposes a ./ui export map), keeping any genuinely objectui-only fields as a local .extend() on top of the imported base rather than a fork.

Why this is a separate project (not a drive-by)

Swapping the import is not a one-liner — objectui runtime code reads objectui-only fields (viewType, fields, the show* flags) that the spec base doesn't have (it uses columns/filter/…). A safe migration needs:

  1. Field-by-field audit of the drift — for each objectui-only field decide: promote into spec, keep as a local .extend(), or drop.
  2. Migrate one schema at a time (ListViewSchema, ObjectViewSchema, FormViewSchema, …), each with a green build + consumer regression pass.
  3. Confirm the runtime read-sites still resolve (grep the show* / viewType / fields consumers).

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions