feat(codegen): FR-024 Increment 2 — B4b cutover + projection codegen for JVM and C##83
Merged
Conversation
Re-enables B4b (ERR_ENTITY_PRIMARY_SOURCE_READONLY) in ValidateObjectPrimarySource and broadens IsReadOnlyProjection() from view-only (DbView != null) to the TS-aligned isReadOnly() semantics — any read-only kind (view/materializedView/ storedProc/tableFunction). Proc-backed object.projections now detect + emit their FR-015 callable as-is (CodegenRunner already iterates all objects; CallableGenerator gates on source-kind, not IsEntity). Migrates the view/proc-primary-entity codegen test fixtures to object.projection; un-ledgers error-entity-primary-source-readonly. Verified locally: dotnet test — Render 290, Conformance 666, Cli 34, Codegen 219 (2 pre-existing fails: TphCodegenTests, IntegrationFixtureDriftTests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
…e codegen Re-enables B4b (ERR_ENTITY_PRIMARY_SOURCE_READONLY) in the Java loader (ValidationPhase.validateObjectPrimarySource). codegen-kotlin stored-proc generator now accepts entity OR projection (gates on the storedProc @kind), so a proc-backed object.projection emits its callable. codegen-spring SpringDtoGenerator appliesTo() includes SUBTYPE_PROJECTION → a view-kind projection gets a read DTO (write surfaces correctly skip it). Migrates the view/proc-primary-entity codegen fixtures+tests (codegen-kotlin, codegen-spring) and FullBasketView (omdb) to the canonical object.projection form; reworks FruitDBTest to write through the Basket entity (read via the projection — a view is read-only). Un-ledgers error-entity-primary-source-readonly. Verified locally: mvn clean install -DskipITs — BUILD SUCCESS (metadata 1055, codegen-spring 142, codegen-kotlin 247, omdb 46, registry-conformance — 0 failures). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
…, tighten test kind-matching
…Kotlin api-docs builders
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.
Intent
Land FR-024 Phase-E Increment 2 — B4b entity-primary-source-readonly cutover + projection codegen fan-out for the JVM (Java codegen-spring + Kotlin) and C# ports (Python's half already on main, 5195ac9). Following the TS reference: B4b makes an object.entity with a primary read-only-kind source illegal (ERR_ENTITY_PRIMARY_SOURCE_READONLY); a derived read model is object.projection. Projection detection uses isReadOnly() (any read-only kind incl storedProc/tableFunction). FR-015 proc-callables gate on source @kind so proc-backed object.projections emit callables. View-kind projections get a read-only DTO. The view/proc-primary-entity codegen TEST fixtures were deliberately migrated to object.projection and error-entity-primary-source-readonly un-ledgered so B4b is enforced cross-port — intentional, not drift. The api-docs finding (JavaApiModelBuilder mislabels projections as value objects + does not document their generated DTO) should be FIXED in this PR (user explicitly approved): label object.projection as unitKind=projection and document its Dto, accurate-by-construction. The 2 C# MetaObjects.Codegen.Tests failures (TphCodegenTests.Entity_subtypes_extend_base, IntegrationFixtureDriftTests) are PRE-EXISTING (red on main before this work, confirmed via git-stash on clean HEAD). Run tests LOCALLY in this isolated worktree. CI (GitHub Actions) skipped — user wants CI done locally and only the PR on GitHub.
What Changed
object.entitywhose primary source resolves to a read-only@kind(view/materializedView/storedProc/tableFunction) is now illegal (ERR_ENTITY_PRIMARY_SOURCE_READONLY), with conformance and unit fixtures migrated from view/proc-primary entities toobject.projectionand the corresponding expected-failure ledgers updated across both ports.SpringDtoGeneratornow applies to projections (read-only<Name>Dto),KotlinStoredProcGeneratorand the FR-015 proc-callable path gate on source@kindso proc-backed projections emit callables, and C# projection detection routes view-kind projections to read-only DbSet + REST routes.object.projectionunits asunitKind=projectionand document their generated<Name>Dto, plus syncedCLAUDE.md,spec/metamodel.md,spec/roadmap.md, anddocs/features/source-kinds.mdfor the cutover.Risk Assessment
✅ Low: A well-bounded, symmetric cross-port cutover whose codegen and api-docs surfaces all delegate inclusion to each generator's appliesTo/kind gate, keeping documented==generated, with the prior round's finding now correctly resolved and fixtures/ledgers migrated consistently.
Testing
test
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
server/java/codegen-spring/src/main/java/com/metaobjects/generator/apidocs/JavaApiModelBuilder.java:105- The projection codegen fan-out is incomplete on the api-docs surface across all three affected ports, breaking the "accurate-by-construction" invariant. This PR makes the generators emit artifacts for object.projection (SpringDtoGenerator.appliesTo now returns true for projections; KotlinStoredProcGenerator emits proc callables; C# DbContextGenerator/RoutesGenerator already gate onIsEntity() || DbView != nullso projections produce a read-only DbSet + read routes), but the api-docs model builders were NOT updated: (1) JavaApiModelBuilder.java:105-106 computesunitKind = entity ? "entity" : "value"and emits the DTO/REST/repository symbols only insideif (entity), so a projection is mislabeledunitKind="value"and its generated<Name>Dtorecord is never documented. (2) CSharpApiModelBuilder.cs:63-65/80 has the identical IsEntity() gate, so a projection's generated read-only DbSet + REST routes go undocumented (RoutesGenerator.cs:45 even comments that the api-docs builder shares its AppliesTo seam, but the builder actually gates onif (entity), not AppliesTo). (3) KotlinApiModelBuilder.kt:68 skips object.projection entirely (continueunless ENTITY or VALUE), so the proc callable it now emits is undocumented. The JavaApiDocsAccuracyTest only checks the forward direction (documented ⊆ generated) and uses no projection fixture, so CI stays green while the docs are inaccurate for real projection usage. The author's stated intent explicitly called out this JavaApiModelBuilder fix (label projection as unitKind=projection + document its <Name>Dto) as in-scope and user-approved, but it did not land in the branch.🔧 Fix: document object.projection units across Java/C#/Kotlin api-docs builders
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
test✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.