Skip to content

fix(detail): TEXTUAL_REF_FALLBACK_TYPES carries both auto-number spellings - #4251

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-4219-autonumber-spelling
Aug 11, 2026
Merged

fix(detail): TEXTUAL_REF_FALLBACK_TYPES carries both auto-number spellings#4251
yinlianghui merged 1 commit into
mainfrom
claude/issue-4219-autonumber-spelling

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes#4219

The re-scoped half of the card: the editability symptom was closed by #4228's alias-aware exclusion (verified and pinned by #4244); what was still owed is the reference-fallback path, which no host gate sits in front of.

The defect, measured on the tip (post-#4244)

TEXTUAL_REF_FALLBACK_TYPES is matched by RAW spelling and carried auto_number only, while @objectstack/spec — and the designer, and the importer — spell the type autonumber. Its one ungated reader is InlineFieldInput's reference fallback, on exported public API:

const isLookupRef =
editType === 'lookup' || editType === 'master_detail' || editType === 'tree' ||
(!!field.reference_to && !TEXTUAL_REF_FALLBACK_TYPES.has(editType as string));

A field typed autonumber keeps a reference_to for relational metadata — which is the entire reason this set exists — so it took the lookup branch and rendered the record picker: a searchable list of records offered as replacements for a machine-generated identity. The auto_number spelling of the identical field rendered the textual fallback, as intended.

The fix is one member plus the rationale in the docblock, matching how plugin-form carries both spellings in each of its non-input sets (deriveMasterDetail.ts:40, :305).

Union survivability

The computed gate and the shared exclusion are a union (#3355). Before this change that union's survivability depended on which spelling the metadata used: autonumber was held by the exclusion gate alone, auto_number by both — so losing either gate would have re-opened a different half of the defect depending on how the field was authored. Both spellings are now members of the computed set, asserted directly on the set rather than described in prose.

Pins (InlineFieldInput.autonumberRefFallback.test.tsx, new file)

The picker and the terminal input both render an input, so every case queries by test id — lookup-trigger* for the picker, inline-plain-text-input for the fallback — rather than by a role heuristic that reads the two as the same thing.

casebeforeafter
autonumber + reference_to renders the textual fallbackRED — the record picker really did rendergreen
auto_number + reference_to unchanged (control)greengreen
a real lookup still gets the record picker (control, over-blocking)greengreen
both spellings in the set, and computed from either side of the unionREDgreen

Reverse verification (git checkout origin/main -- fieldEnrichment.ts, re-run, restore — never git stash): predicted RED on exactly the two cases that read the set, with both controls staying green. Observed exactly that — Tests 2 failed | 2 passed (4), the failure on case 1 dumping the lookup-trigger button DOM. Restored and re-confirmed green.

Verification

  • npx vitest run packages/plugin-detail/72 files, 728 tests passed. The Inline edit still destroys array-valued and container field values on the detail page (the rest of the #4216 fall-through sweep) #4220 partition table in inlineEditTypeCoverage.test.tsx is unmoved: autonumber and auto_number were already in the excluded bucket (the exclusion gate put them there), so widening the computed gate adds no second claim.
  • pnpm --filter @object-ui/plugin-detail type-check — clean.
  • pnpm --filter @object-ui/plugin-detail lint — 0 errors (759 pre-existing warnings, none in the touched files).
  • node scripts/check-control-bytes.mjs — OK, plus a direct control-byte scan of both touched files.
  • Build closure pnpm --filter '@object-ui/plugin-detail^...' build ran before any of the above. No exported TYPE changed — this is a Set literal's contents — so no downstream consumer sweep was owed; the public surface is byte-identical.
  • Changeset: @object-ui/plugin-detail patch.

Sweep, and one finding

Swept plugin-detail for sibling spelling-sensitive type sets. The auto-number family has no other gap here. One different family does, filed as #4250 rather than fixed in this PR: the spec spells richtext, and four sets across three packages spell it rich_text / rich-text (RelatedList's SKIP_TYPES, both autoLayout implementations, RecordDetailView's SECONDARY_FIELD_TYPES) — none of which any producer emits. It spans packages outside this card and carries a design call (whether markdown joins SKIP_TYPES, whether the dead spellings are dropped), and fixing only the plugin-detail halves would make the detail page and the form disagree about the same field.


Generated by Claude Code

…lings (#4219)
The set is matched by raw spelling and carried `auto_number` only, while the
spec / designer / importer spell the type `autonumber`. Its one ungated reader
is `InlineFieldInput`'s reference fallback on exported public API, so an
`autonumber` carrying a `reference_to` — computed fields keep one for relational
metadata — resolved into the record picker, offering records as replacements for
a machine-generated identity.
Adds `autonumber` beside `auto_number`, matching plugin-form's both-spellings
convention, and documents why the set is spelling-sensitive. Pins the
reference-fallback path (red before the change), `auto_number` and a real
`lookup` as controls, and set membership directly so the gate union no longer
depends on which spelling the metadata uses.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
@vercel

vercelBot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectuiIgnoredIgnoredAug 11, 2026 7:43am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)28.3 KB350 KB
Entry fileindex-C1XGltIZ.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)8.88KB3.25KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)7.57KB2.97KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)22.10KB4.37KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.13KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.64KB2.21KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)35.76KB9.11KB
auth (createAuthenticatedFetch.js)4.37KB1.69KB
auth (index.js)2.35KB1.07KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)4.91KB0.87KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)26.07KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.65KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)488.60KB108.25KB
core (index.js)3.04KB1.15KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)144.34KB37.61KB
fields (index.js)228.43KB56.61KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.32KB1.77KB
i18n (index.js)2.65KB1.06KB
i18n (pickLocalized.js)1.70KB0.83KB
i18n (provider.js)9.48KB3.27KB
i18n (useObjectLabel.js)27.59KB6.63KB
i18n (useSafeTranslation.js)4.52KB1.96KB
layout (index.js)38.98KB10.85KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)8.75KB3.06KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)3.67KB1.12KB
permissions (evaluator.js)4.41KB1.44KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.55KB0.71KB
plugin-ai (index.js)15.71KB3.79KB
plugin-calendar (index.js)45.23KB12.45KB
plugin-charts (index.js)61.52KB17.49KB
plugin-chatbot (index.js)180.33KB42.79KB
plugin-dashboard (index.js)118.58KB30.71KB
plugin-designer (index.js)210.91KB42.67KB
plugin-detail (index.js)238.87KB59.70KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)114.58KB27.68KB
plugin-gantt (index.js)164.14KB39.98KB
plugin-grid (index.js)187.97KB49.90KB
plugin-kanban (index.js)48.60KB13.41KB
plugin-list (index.js)110.31KB26.76KB
plugin-map (index.js)17.00KB5.32KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)40.58KB10.58KB
plugin-timeline (index.js)26.21KB7.52KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.03KB20.55KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.71KB3.53KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.67KB2.37KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)23.71KB7.96KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.23KB0.66KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)4.09KB1.74KB
sdui-parser (index.js)4.47KB2.03KB
sdui-parser (parse.js)10.04KB2.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)4.69KB1.48KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)3.05KB1.52KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@yinlianghui
yinlianghui marked this pull request as ready for review August 11, 2026 07:51
@yinlianghui
yinlianghui added this pull request to the merge queueAug 11, 2026
Merged via the queue into main with commit 6d01319Aug 11, 2026
21 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-4219-autonumber-spelling branch August 11, 2026 07:52
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A field typed autonumber (the spec spelling) is inline-editable on the detail page, so a user can overwrite a machine-generated value

2 participants

@yinlianghui@claude