Immutable
release. Only release title and notes can be modified.
Added
- Generic entity persistence (
[Entity],Insert<T>/Update<T>/Store<T>/Delete<T>,
IStorageAction<T>). MongoDB now implements Wolverine's generic persistence surface for
any plain document type, not justSagasubclasses — closing the one functional gap vs
Cosmos and RavenDb.[Entity]handler parameters load a document by id before the handler
runs; returningInsert/Update/Store/Delete<T>or anIStorageAction<T>persists it
afterward, atomically with the outbox on the same MongoDB transaction session.CanPersistis now unconditionaltrue(previously scoped toSagasubclasses) —
the saga-vs-entity distinction moved into the frame factories, which branch on
variable.VariableType.CanBeCastTo<Saga>(). Saga behavior, OCC, and collection naming
are unchanged.- Collection naming: one un-prefixed collection per entity type,
<lowercased-type-name>(e.g.OrderNote→ordernote) — distinct from sagas'
wolverine_saga_prefix, since entity collections are application data. - Write semantics:
Insert/Update/Storeall upsert (ReplaceOneAsync(IsUpsert=true),
matching Cosmos); no optimistic concurrency for plain entities — use the repository
pattern for app-controlled OCC. The entity's_idis extracted via the MongoDB driver's
class map (BsonClassMap...IdMemberMap), not a.ToString()coercion. - Coverage: Wolverine's upstream
StorageActionCompliancesuite passes (all facts) via
storage_action_compliance.cs. Custom tests cover entity write + outbox atomicity, and
saga/entity coexistence in the same handler (frame-branching regression guard). Full
single-node suite green on net9.0 + net10.0; cross-node entity persistence verified under
DurabilityMode.Balanced. - Demo:
OrderNoteHandlerdemonstratesInsert/[Entity]+Update/[Entity]+Delete
against a realOrderNotedocument, wired toPOST/DELETE /orders/{id}/notesendpoints.
- Saga store diagnostics (
ISagaStoreDiagnostics). MongoDB now implements Wolverine's
read-only saga-explorer surface — matching RavenDb, and above Cosmos, which does not
implement it — so CritterWatch and other monitoring tools can list the Mongo-owned saga
types, read a single saga instance by id, and peek at recent instances. Registered
automatically byUseMongoDbPersistence. Reads run against thewolverine_saga_<type>
collections with native_idmatching (no string coercion);countis clamped to
[0, 1000]; descriptors are tagged"MongoDb". Registration does not affect startup or
the existing inbox/outbox/saga behavior (full single-node suite green on net9.0 + net10.0). MongoDbUnitOfWorkdemo example.RecordOrderAuditHandlershows the no-repository
write path — a handler that acceptsMongoDbUnitOfWorkdirectly and writes through
Collection<T>(name), with the session threaded automatically — alongside the existing
repository +IClientSessionHandleexample, wired toPOST /orders/{id}/audit.- Saga-cascade read-model consumer in the demo.
FulfillmentStatusProjectorconsumes
OrderFulfillmentSaga'sFulfillmentShippedEvent/FulfillmentCompletedEventcascades via
a durable local queue and maintains afulfillment_delivery_statusesread model, exercising
the full saga → outbox → consumer path end to end.
Changed
- Multinode leadership compliance is no longer compile-gated. The upstream
LeadershipElectionCompliancesuite (previously behind#if RUN_MULTINODEbecause earlier
WolverineFx releases required a leadership-race ordering guarantee this provider's
w:majoritylock could not make) now runs unconditionally as part of CI's multinode step,
after WolverineFx 6.9.0 reworked the underlying facts around the "any healthy node leads"
model this provider already implements. Verified 5× consecutive green on net9.0 and net10.0
before un-gating.