Notification Event Envelope
Summary
NotificationEventEnvelope is a sealed record of 11 fields plus one computed property. It is the service's normalised view of a delivery, built from AMQP properties, headers and the body.
Audience
Engineers, architects, QA, support and security reviewers.
Reference Content
The verified reference material for this topic is set out in the sections below.
Fields
| Field | Type | Source on the wire | Used downstream |
|---|---|---|---|
EventId | GUID | Message id, else the EventId header | Yes — idempotency key |
EventType | string | Type property, else the EventType header, else the routing key | Yes — resolver switch |
CorrelationId | string? | Correlation id property, else the CorrelationId header | Yes — audit and messages |
CausationId | string? | CausationId header | No |
TenantId | string? | TenantId header | Yes — tenant scoping |
UserId | string? | UserId header | No |
SourceService | string | SourceService header, else the literal unknown | Yes — idempotency ledger |
OccurredAtUtc | timestamp | OccurredAtUtc header | Yes — staleness check |
SchemaVersion | int | SchemaVersion header | No |
PayloadJson | string | The message body, decoded as UTF-8 | Yes — deserialized per event |
ForceFail | bool | x-force-fail header | Yes — test affordance |
Three fields — causation identifier, user identifier and schema version — are parsed onto the envelope and then never read by any downstream code. They are carried for future use.
Computed correlation
The record exposes an effective correlation identifier that falls back to the event identifier when the producer sent none, so correlation is never null for tracing purposes. Note that the raw nullable field is what gets persisted onto messages and audit rows; see correlation.
Parsing fallbacks
Every field has a defined fallback, so a malformed or sparse message still produces a usable envelope rather than an exception.
| Field | Fallback chain |
|---|---|
| Event identifier | Message id → header → newly generated GUID |
| Event type | Type property → header → routing key |
| Occurrence | Header → current instant |
| Schema version | Header → 1 |
| Source service | Header → unknown |
| Correlation | Property → header → null |
The event-identifier fallback matters. A message arriving with neither a message id nor an EventId header receives a freshly generated identifier, which is unique on every delivery. Such a message can never be recognised as a duplicate, so redelivery would reprocess it. See idempotency.
Header decoding
Header values arrive as byte arrays, strings or other objects. A decoder normalises all three: byte arrays are decoded as UTF-8, strings pass through, anything else uses its string representation, and null yields null.
Publisher-side symmetry
The shared event bus writes exactly the header set the consumer reads — event identifier, event type, correlation, causation, tenant, user, source service, occurrence and schema version — and additionally sets the message id, correlation id, type, content type, persistent delivery mode and a timestamp as AMQP properties.
Metadata entries with blank values are filtered out before headers are written, so an absent value produces a missing header rather than an empty one, which is why the consumer's fallbacks are needed.
Verified absence
The envelope carries no signature, no encryption marker, no content-type negotiation, no compression flag, no retry counter and no dead-letter reason.
Classification
Implemented.
Requires confirmation
Whether the three unused fields are intended to drive behavior requires confirmation.
Related Articles
See Also
Keywords
- Notification database
- Event Envelopes
- Draft database documentation
Source References
microservices/src/notification-service/Messaging/NotificationEventEnvelope.csmicroservices/src/notification-service/Messaging/NotificationEventConsumer.csmicroservices/src/shared-kernel/Messaging/RabbitMqEventBus.csmicroservices/src/notification-service/Api/NotificationEndpoints.cs
Revision Information
- Status: Draft
- Last reviewed: 2026-07-21
- Review cycle: Quarterly