Skip to content

fix(driver-sql): round-trip rating/slider/toggle with type fidelity#2025

Merged
os-zhuang merged 2 commits into
mainfrom
fix/field-type-fidelity-v2
Jun 18, 2026
Merged

fix(driver-sql): round-trip rating/slider/toggle with type fidelity#2025
os-zhuang merged 2 commits into
mainfrom
fix/field-type-fidelity-v2

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Problem

The dogfood field-zoo round-trip test (#2022) surfaced three authorable field types that persist but read back with the wrong JS type over the REST data API:

field write read back (before)
rating 4 '4' (string)
slider 25 '25' (string)
toggle true '1' (string)

The value is not lost — only the type leaks. On a low-code platform where an AI authors arbitrary field types, a field that silently returns the wrong type is a runtime-fidelity trap the static gates and value-loss tests don't catch.

Root cause (packages/plugins/driver-sql/src/sql-driver.ts)

Two coupled gaps:

  1. Wrong column affinity. createColumn's DDL switch had no case for rating/slider/toggle/progress, so they fell to default → table.string = TEXT affinity. SQLite then coerced the written number/boolean to a string on storage. number/currency/percent worked only because of explicit table.float cases; boolean because of a table.boolean case + read coercion.
  2. Missing read coercion. formatOutput re-types boolean columns via the booleanFields registry, keyed on type === 'boolean' only — toggle was never registered.

Fix

  • rating/slider/progress → REAL (numeric) column.
  • toggle → boolean column and registered in booleanFields so stored 1/0 coerce back to a real JS boolean.
  • Audit of the other raw-literal types: vector/composite/repeater were already JSON-safe; record/video/audio were the same latent leak (object → TEXT), now folded into the shared JSON_COLUMN_TYPES set. tree stores a reference id (string→string, no leak — unchanged).
  • The DDL default case now derives JSON-vs-string from JSON_COLUMN_TYPES, so the column-type switch and isJsonField (read side) can no longer drift.

Verification

  • New driver-layer unit test sql-driver-numeric-fidelity.test.ts asserts typeof fidelity for rating/slider/progress/toggle + record/video/audio. Red-proof done: all 3 fail without the fix, pass with it.
  • Full driver-sql suite: 158 passed, no regressions.
  • Lifted the xfail quarantine on rating/slider/toggle in the dogfood matrix → real-HTTP round-trip test now 22 passed (the formerly-quarantined three turn green — exactly the signal the it.fails quarantine was designed to force).

🤖 Generated with Claude Code

os-zhuang and others added 2 commits June 18, 2026 14:28
rating/slider/toggle (and progress) fell to the DDL switch `default`
case → table.string, giving the column TEXT affinity. SQLite then
coerced the written number/boolean to a string ('4' not 4, '1' not
true): the value persisted but the JS type leaked on read. On a
low-code platform where an AI authors arbitrary field types, a field
that silently returns the wrong type is a runtime-fidelity trap the
static gates and value-loss tests don't catch.

- map rating/slider/progress → REAL (numeric) column
- map toggle → boolean column + register it in booleanFields so the
  read path coerces stored 1/0 back to a real JS boolean
- fold object-valued record/video/audio into the shared
  JSON_COLUMN_TYPES source, and drive the DDL default off that set so
  the column-type switch and isJsonField can no longer drift
- driver-layer unit test (sql-driver-numeric-fidelity) + lift the
  xfail quarantine on rating/slider/toggle in the dogfood matrix

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 18, 2026 6:36am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Jun 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/dogfood, @objectstack/driver-sql.

8 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/core/plugins.mdx (via @objectstack/driver-sql)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/driver-sql)
  • content/docs/concepts/terminology.mdx (via @objectstack/driver-sql)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-sql)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/driver-sql)
  • content/docs/guides/packages.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/objectos/index.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/driver-sql)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit 1d352d3 into main Jun 18, 2026
15 checks passed
@os-zhuang
os-zhuang deleted the fix/field-type-fidelity-v2 branch June 18, 2026 06:44
os-zhuang added a commit that referenced this pull request Jun 18, 2026
…ns + extend dogfood matrix (#2028)

The #2025 column-affinity fix only governs newly created columns: SQLite
never alters a column's type in place and the reconciler only adds
missing columns, so a rating/slider/progress column created before the
fix keeps TEXT affinity and still reads back '4' not 4.

- add a read-side numeric coercion (numericFields registry, single-
  sourced from NUMERIC_SCALAR_TYPES) that coerces numeric-looking stored
  strings back to numbers on read — mirroring the dateFields legacy
  repair — so fidelity no longer depends on column affinity alone; null
  and non-numeric junk are preserved (not 0/NaN)
- unit test: reproduce a legacy TEXT column and prove it self-heals
- extend the dogfood HTTP matrix to guard progress/record/video/audio
  over real HTTP (previously only driver-unit-tested)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 18, 2026
os-zhuang added a commit that referenced this pull request Jun 27, 2026
feat(studio): remove the "Local / Custom" stopgap scope from the package selector (ADR-0070 D5) (#2025)

objectui@17ae00cb569379298a99d21e4c52432c9def43aa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant