Skip to content

Release v20.39.1

Choose a tag to compare

@github-actions github-actions released this 05 Jun 12:53
1997e48

Summary

The Chronicle read model interceptor (PII release) is registered for every read model, so QueryPipeline.ApplyInterceptors ran it against observable (ISubject<T>) and async-enumerable query results. It handed the streaming wrapper to IInterceptReadModel<TReadModel>.Intercept(TReadModel), throwing Object of type 'LifetimeAwareSubject<…>' cannot be converted to type '<ReadModel>' and breaking every observable model-bound query served over the multiplexed SSE/WebSocket hub. Streaming interception now lives behind a single helper shared by all streaming transports, so compliance/PII release runs per emission — including for collection queries, which previously skipped it.

Fixed

  • Observable (ISubject<T>) and IAsyncEnumerable<T> model-bound query results no longer crash under read model interception. QueryPipeline.ApplyInterceptors now leaves streaming results untouched for the streaming transport to intercept per emission.
  • Collection observable queries (ISubject<IEnumerable<TReadModel>>) now have compliance/PII release applied to each item. The streaming transports previously keyed interception on the enumerable type, found no matching interceptor, and silently served undecrypted values.

Changed

  • All streaming transports (ObservableQueryDemultiplexer, ClientObservable, ClientObservableSSE, ClientEnumerableObservable, ClientEnumerableObservableSSE) now share a single IReadModelInterceptors.InterceptEmission helper that intercepts each emission, unwrapping collection emissions to the read model element type.

🤖 Generated with Claude Code