Skip to content

GH-3627: document [StreamState] and [StreamEvents] - #4121

Merged
jeremydmiller merged 1 commit into
mainfrom
gh-3627/document-stream-reads
Aug 25, 2026
Merged

GH-3627: document [StreamState] and [StreamEvents]#4121
jeremydmiller merged 1 commit into
mainfrom
gh-3627/document-stream-reads

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

[StreamState] and [StreamEvents] shipped in 6.30 with no documentation anywhere — nothing under docs/guide mentioned them. This fills that in.

What's added

  • docs/guide/handlers/persistence.md — a ### Raw Stream Reads section under Event Sourced Models, which is where the store-agnostic vocabulary lives. Two new rows in the vocabulary table at the top.
  • docs/guide/http/marten.md — a section next to [ReadAggregate], reusing the sample_using_streamstate_and_streamevents_in_http region that already existed in Orders.cs.
  • EventSourcedModelSamples.cs — three new worked samples.
  • MartenTests/stream_state_and_events_handlers_3627.cs — message-handler coverage this path never had.

The identity convention gets a callout

This is the part worth reviewing. [Entity] Order order can infer an identity member named OrderId, because the parameter's own type names your entity. The parameter type for these attributes is StreamState — the store's vocabulary, not your aggregate — so tryFindIdentityVariable looks for "StreamStateId", and in practice only a member literally named Id resolves without help.

Verified rather than reasoned about. A handler taking ProbeFindByOrderId(Guid OrderId) with a bare [StreamState] fails at bootstrap:

Wolverine.Persistence.InvalidEntityLoadUsageException :: Unable to determine a value
variable named '' and source Anything to load an entity of type
JasperFx.Events.StreamState for parameter state

Fails fast rather than silently, which is the important part. (Minor observation, not addressed here: the message renders the variable name as empty quotes, so it does not name the member it looked for.)

Why a test came with the docs

Only the HTTP path had coverage (Wolverine.Http.Tests/Marten/stream_state_and_events_3627.cs), and its endpoints use a {id} route argument — which happens to be exactly the case the convention handles. The handler path, where the convention bites, had none. The new test pins both the Id convention and the explicit [StreamState("AggregateId")] form.

Verification

  • dotnet build wolverine.slnx -c Release -f net9.0 — clean, 0 warnings
  • New MartenTests class — 2/2 passing
  • mdsnippets run; unrelated pre-existing snippet drift in 84 other files was reverted rather than swept into this PR

🤖 Generated with Claude Code

These shipped in 6.30 with no documentation at all. Adds the store-agnostic
treatment to the persistence helpers guide, an HTTP-side section next to
[ReadAggregate], and worked samples.

The identity convention gets a callout because it is genuinely surprising:
[Entity] Order infers "OrderId" from the parameter's own type, but the
parameter type here is StreamState -- the store's vocabulary, not the
aggregate -- so the "<ParameterType>Id" rule looks for "StreamStateId" and
only a member literally named "Id" resolves without help. Verified: a miss
throws InvalidEntityLoadUsageException at bootstrap.

Also adds the message-handler test coverage that path never had. Only the
HTTP side was tested, and the handler side is where the identity convention
bites.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jeremydmiller
jeremydmiller merged commit 52f2b55 into main Aug 25, 2026
73 of 74 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant