You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docs: surface entity read-views (FR-024 §7) as the on-ramp for legacy "SELECT A.*, extras" views + entity-vs-projection decision table #206
FR-024 §7 "view behavior on the entity" is shipped — an object.entity may carry a non-primarysource.rdb @kind:view plus derived (origin.*) fields; writes route to the table, reads to the view, derived fields are read-only + excluded from write codecs, and meta migrate emits the view DDL (2026-06-12-fr-024-entity-surfaces-projections-design.md:251,386; loader ERR_DERIVED_FIELD_NO_READ_SOURCE, validation-passes.ts:1355). But docs/features/source-kinds.md reads as "read-only @kind ⇒ projection, full stop," so an adopter migrating a legacy SQL-view-heavy schema reaches for object.projection and immediately hits "enumerate every column" (the wildcard was removed at B4b, extract-view-spec.ts:598).
The result is that the single most common legacy view shape is modeled the hard way (or not at all).
The pattern that needs an on-ramp
CREATEVIEWorder_with_customerASSELECT o.*, c.nameAS customer_name -- the entity's own columns + a joined extraFROM orders o, customers c
WHEREo.customer_id=c.id;
This is not a projection — it is the Order entity with a read route. The entity's own field set is the o.*; only the extra (customerName via the customer_id reference) needs declaring, as a derived origin.passthrough field. One node, one generated class, writes→table, reads→view.
Ask (docs + adoption; no metamodel change)
Surface entity read-views prominently in source-kinds.md / the adoption docs as the first answer for SELECT A.*, extras FROM A … legacy views — today the docs point straight at projection.
Add an entity-vs-projection decision table:
Use an entity read-view when
Use a projection when
extras sit over the entity's own table
it is an independent exposure contract
same read trust-domain (a new entity field appearing in the view is correct, not a leak)
you can still INSERT the base and it's the record of truth
keyless, multi-base, or proc-backed; all-derived, borrowed/no identity
State the honest boundary that still pushes to a projection (or other FRs): renamed base columns (a field carries one @column per paradigm — a rename-in-view is the projection's whole point), and row-filtered views (no view-level WHERE yet — separate filter FR).
Why it matters
The entity-read-view path is the cleanest home for the largest class of legacy views and is already implemented — it just isn't discoverable. A short docs pass + a decision table turns "re-enumerate 40 columns as a projection, or hand-write the view" into "add the read source and the extra derived fields."
Shipped in the coordinated 0.17.0 (npm / PyPI / NuGet) · 7.9.0 (Maven Central) release — live on all four registries (PR #215, tag v0.17.0). Cross-port, conformance-gated. See CHANGELOG [0.17.0].
Activity
docs(roadmap): track the projection/view-materialization epic (#206-212)
docs(#206): entity read-view on-ramp for legacy SELECT A.* views + de…
docs(#206): mark the entity-read-view schema pipeline as pending #213 …
fix(#213): emit the entity read-view's replica view (isWriteThrough →…
docs(#213): entity-read-view status — schema half shipped, read half is
docs: accuracy pass for the 0.17.0/7.9.0 feature bundle (#195/#207/#214)
dmealing commentedon Jul 18, 2026
Shipped in the coordinated 0.17.0 (npm / PyPI / NuGet) · 7.9.0 (Maven Central) release — live on all four registries (PR #215, tag
v0.17.0). Cross-port, conformance-gated. See CHANGELOG [0.17.0].