@@ -64,14 +64,39 @@ value → set). Notes:
6464 PATCH's present-null-on-` @required ` is still rejected (explicit guard), but a
6565 present-VALUE subtype constraint is not enforced (Java, using per-subtype ` <Sub>Dto ` ,
6666 does enforce it). Minor pre-existing divergence, untested by any gate.
67- - ** Object/value-typed columns are non-PATCHable (deliberate, cross-port).** A
68- ` field.object ` /` field.map ` column (VO → jsonb, single or ` @isArray ` ) — and a
69- ` field.string @dbColumnType=jsonb ` open-bag — are EXCLUDED from the patch settable
70- set (` patchSettableFields ` skips ` ObjectField ` /` MapField ` /` isJsonbOpenBag ` ), so a
71- ` PATCH ` leaves them untouched. This is a ** deliberate cross-port Day-1 simplification**
72- (Java + Kotlin exclude ` ObjectField ` ; C# skips the owned-nav) — NOT a per-port bug.
73- Making VO/open-bag columns PATCHable is a separately-scoped cross-port follow-up FR;
74- a single-port fix would break the api-contract byte-identical parity.
67+ - ** Object/map-typed columns: PATCHability is per shape (split by Program D).** The
68+ blanket rule this bullet used to carry — a ` field.object ` /` field.map ` column is
69+ EXCLUDED from the patch settable set, so a ` PATCH ` leaves it untouched — is stale
70+ for one shape. What the vanilla path's ` patchSettableFields ` does today, shape by
71+ shape:
72+ - ` field.object @storage jsonb ` (the storage default, single or ` @isArray ` ) —
73+ SETTABLE: a present value binds via Jackson ` treeToValue ` into the VO record /
74+ ` List<VO> ` and is validated in full; a present ` null ` clears a nullable column
75+ or 400s a ` @required ` one; absent → untouched (the FR-035 tristate). The
76+ sibling ` codegen-spring ` module's ` KNOWN_GAPS.md ` records the shipment as
77+ cross-port (TS / Python / Java / Kotlin / C#), gated by
78+ ` fixtures/api-contract-conformance/jsonb/scenarios/jsonb-value-object-patch.yaml ` .
79+ - ` field.object @storage flattened ` — EXCLUDED: the Exposed table materialises it
80+ as per-subfield columns; there is no single ` Table.<field> ` to bind.
81+ - ` field.map ` — EXCLUDED (` it !is MapField ` ): dict-of-VO, staged out.
82+ - ` field.string @dbColumnType=jsonb ` open-bag — EXCLUDED (` isJsonbOpenBag ` ):
83+ create-only (next bullet); its PATCH is the tracked Kotlin follow-up (the
84+ kotlinx ` parseToJsonElement ` bridge) the sibling ` codegen-spring `
85+ ` KNOWN_GAPS.md ` lists under "Still staged out".
86+ The remaining exclusions are deliberate staging (each for the substrate reason
87+ above), not per-port bugs — save the map one, which is a live divergence from
88+ Java and C# (both patch map columns; C#'s G7 records the split). Closing any of
89+ them is separately-scoped follow-up work, not a piecemeal port fix.
90+ ** TPH residual.** The per-subtype path has its own SSOT —
91+ ` KotlinTphPlan.subtypeSettableFields ` still filters ` ObjectField ` out outright —
92+ so a VO column on a TPH-rooted entity is skipped on PATCH, the same TPH
93+ staging-out Java's and C#'s entries record.
94+ ** Close status.** With the jsonb-VO shape settable, what remains here may mean
95+ the gap this bullet tracked is already closed; that ruling is deliberately NOT
96+ made here because it needs Program D's intent, which this file does not own. It
97+ is filed for exactly that decision as
98+ [ issue #359 ] ( https://github.com/metaobjectsdev/metaobjects/issues/359 ) . Until
99+ ruled, the entry stays open against the residuals above.
75100- ** ` field.string @dbColumnType=jsonb ` open-bag** is a ** create-only** column on the
76101 generated CRUD. The generated ` create ` writes it (bound from the ` @Valid ` DTO's
77102 kotlinx ` JsonElement ` property — exercised by the ` jsonb-open-bag-roundtrip ` corpus),
0 commit comments