Skip to content

Docs: surface entity read-views (FR-024 §7) as the on-ramp for legacy "SELECT A.*, extras" views + entity-vs-projection decision table #206

Description

@dmealing

Summary

FR-024 §7 "view behavior on the entity" is shipped — an object.entity may carry a non-primary source.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

CREATE VIEW order_with_customer AS
  SELECT o.*, c.name AS customer_name          -- the entity's own columns + a joined extra
  FROM   orders o, customers c
  WHERE  o.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)

  1. 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.
  2. 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) subset / renamed columns / versioned / external consumers
you can still INSERT the base and it's the record of truth keyless, multi-base, or proc-backed; all-derived, borrowed/no identity
  1. 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."

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:metamodelMetamodel vocabulary / loaderdocumentationImprovements or additions to documentation

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions