Skip to content

Read models without a declarative projection: reducers and computed views are undeclarable #39

Description

@woksin

Summary

The projection sub-language (PDL) is the only way a document can define a read model, and it is declarative-only. Two read-model shapes that Arc supports as first-class citizens therefore cannot be described:

  1. Reducers — read models folded from events by code (IReducerFor<T>). The fold logic legitimately lives in code; but the document cannot even say "this read model is reduced from these events by this file", the way reactor, constraint, and command handler already pair a declarative header with a file reference.
  2. Computed read models — models with no event feed at all, composed by querying over other read models. They surface in the document only as query return types, with no definition anywhere.

Evidence (real application)

Generating from Ada (Cratis.Arc.Screenplay 20.65.0):

  • 9 × SP0020 [Warning] '<X>Reducer' folds events into '<X>' with code, which Screenplay has no counterpart for, so only the events it observes are stated (e.g. CustomerCandidateReportReducer, CustomerRequestWorkspaceReducer). The emission masquerades as a mapping-less projection — a reader cannot tell a reducer from an underspecified projection.
  • 13 read models in the source are computed/query-only (compose over other read models) — they have no definition in the document at all.

Suggested direction

  1. A reducer construct symmetric with the existing code-carrying constructs:
reducer CustomerCandidateReport => CustomerCandidateReport
  on RequestCandidatePresented
  on RequestCandidateWon
  file CustomerPortal/Report/Report.cs

(observed events are declarative and validator-checkable; the fold stays in code, exactly like a reactor's handler.)

  1. For computed read models, at minimum a declaration that names the model and the read models it composes over (readmodel X from Y, Z + file), so the document introduces every type its queries return.

Context

Found while validating a generated 5,348-line document from a production Arc application against its source. Related: #29 (complex value types), #30 (one projection per slice).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions