Repository navigation
fix(codegen-ts): emit one Drizzle column per member for flattened value objects - #538
Merged
Merged
Conversation
…; skip value objects
…: source-kinds, api-contract, field-types. No unresolved gaps.
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.
What Changed
codegen-tsnow binds afield.object @storage: flattenedto its member columns, named byresolveFlattenedColumnName, instead of onejsonbcolumn for the field. This matches whatmeta migratecreates, so generated queries no longer fail with undefined-column errors (codegen-ts: Drizzle binds a flattened value object as one jsonb column that migrate never creates #524).shipToStreet). A flattened field on a write-through entity is refused with aCodegenError. A flattened field on a TPH subtype keeps a single column, as migrate does.flattened.tshelper, the matching template and example updates, and tests (flattened-storage-e2e.test.ts,form-flattened-storage.test.ts). Adds a CHANGELOG entry under Fixed.Validation
Risk Assessment
✅ Low: After eight fix rounds, the flat surface is consistent across Drizzle, Zod, types, filter and sort, OpenAPI, the docs, the form and the grid, and it matches migrate's columns, with end-to-end coverage. The one remaining gap (a derived flattened parent) is a narrow edge case.
Testing
Ran the e2e and unit tests for flattened storage, then drove the real
metaCLI on a throwaway sqlite project.meta genemitted Drizzle columnsshipToStreet,shipToCityand so on, in line with theship_to_*andbill_to_*columns thatmeta migratecreated. Queries and Hono routes then worked against that DB. Inserts, updates, reads and listing returned flat keys. A filter onshipToCityand a sort byshipToCityworked. A filter onshipToor on the non-filterableshipToStreetwas rejected with a 400. The generated code passedtsc --strict. The fullscripts/ci-local.sh --quick --strict-toolchainspassed; it skips the other-language ports, the Java reactor and the docker suite. The Postgres dialect check ran only through the e2e test's parity assertion, not live. Scratch files were removed and the worktree is clean.meta genandmeta migrate --applyon a throwaway project: up.sql has ship_to_street/city/floor and bill_to_*; generated Shipment.ts has shipToStreet etc. bound to the same names, and no `ship…shipToor non-filterable membershipToStreetis rejected, and a nested insert body does not write membersshipToinsert is stripped without error, so the members stay nulltsc --strictover src/generated gave no errorsEvidence: Live queries against migrated sqlite DB
Evidence: Live Hono routes (POST/PATCH/filter/sort/rejected filters)
Evidence: ci-local --quick full log
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
server/typescript/packages/codegen-ts/src/flattened.ts:260-flatSurfaceFieldsexpands a flattenedfield.objecteven when the parent field is derived (carries anorigin.*), andasFlatKeyforwardsisDerived()to the member, not the parent. The Drizzle table (drizzle-schema.ts:362) andmeta migrate(expected-schema.ts:636) both skip a derived parent, so no member columns exist. The flat surface still offersshipToStreetetc. as non-derived keys. They appear in the read, insert and update schemas (zod-validators.ts:603, :611, :621), the filter and sort allowlists, the OpenAPI bodies and the form. Before this change the derived parent was excluded from the write schemas. Nothing errors: a write silently drops the keys, and the Row/read contract claims columns that do not exist. The case is narrow, but the loader allowsorigin.*on an entity field. Fix: inflatSurfaceFields, return[f]unchanged (or[], to match Drizzle) whenf.isDerived(), or make the proxy report the parent'sisDerived().This ships as a separate follow-up PR right after this one merges, not in this PR.
✅ **Test** - passed
✅ No issues found.
meta genandmeta migrate --applyon a throwaway project: up.sql has ship_to_street/city/floor and bill_to_*; generated Shipment.ts has shipToStreet etc. bound to the same names, and no `ship…shipToor non-filterable membershipToStreetis rejected, and a nested insert body does not write membersshipToinsert is stripped without error, so the members stay nulltsc --strictover src/generated gave no errorsscripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainsbun test test/flattened-storage-e2e.test.ts test/names-flattened.test.tsin codegen-ts (30 pass)bun test test/form-flattened-storage.test.tsin codegen-ts-react (1 pass)Live:meta init,meta gen,meta migrate --from-db --applyandmeta migrate apply-pendingon a throwaway sqlite project with two flattenedfield.objectfields; generated entity, queries and routes inspected andtsc --strictrun over themLive: ran the generatedcreateShipment,updateShipment,findShipmentByIdandlistShipmentsagainst the migrated sqlite DB (bun drive.ts)Live: mounted the generated Hono routes and sent POST, PATCH, GET with filter and sort, and rejected-filter requests against the migrated DB (bun drive2.ts)scripts/ci-local.sh --quick --strict-toolchains(exit 0, LOCAL CI PASSED, 4 gates skipped by design: other-language ports, Java reactor, docker suite, cube check)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
Fixes #524
Gate runs: 3. Run 1 failed on the gate daemon failing to fetch
main(ssh permission denied), run 2 died in the test step on a model usage limit, and run 3 passed. Prisma already exposes flat keys (shipToStreet) and was not changed.