Notification Integration Event Contracts
Summary
Notification deserializes consumed payloads into 14 contract types: 10 shared contracts from the platform contracts assembly and 4 service-local payload records declared privately inside the resolver.
Audience
Engineers, architects, QA, support and implementation partners.
Reference Content
The verified reference material for this topic is set out in the sections below.
Shared contract base
The platform declares an abstract IntegrationEvent record carrying event identifier, event type, occurrence timestamp, correlation and causation identifiers, tenant and user identifiers, source service and schema version. Publishing services derive concrete contracts from it.
Notification does not deserialize into the base type. It deserializes the message body into the specific payload type for the event, using web-style JSON options, and reads the envelope metadata separately from AMQP properties and headers.
Shared contracts consumed
Ten types are referenced from the shared contracts assembly:
| Contract | Event |
|---|---|
EmployeeCreatedEvent | EmployeeCreated |
LeaveApprovedEvent | LeaveApproved |
LeaveRejectedEvent | LeaveRejected |
PayrollFrozenEvent | PayrollFrozen |
PayslipGeneratedEvent | PayslipGenerated |
DocumentGeneratedEvent | DocumentGenerated |
TenantProvisionedEvent | TenantProvisioned |
ExpenseApprovedEvent | ExpenseApproved |
ExpenseRejectedEvent | ExpenseRejected |
ExpensePaidEvent | ExpensePaid |
These are genuinely shared types: the publishing service and Notification compile against the same definition, so a change to one is a compile-time change for both.
Service-local payload records
Four private records are declared inside the resolver and cover the remaining 32 event types:
| Record | Covers | Types |
|---|---|---|
AssetEventPayload | Asset lifecycle | 6 |
PerformanceEventPayload | Performance lifecycle | 7 |
TrainingEventPayload | Training and certification | 9 |
HelpdeskEventPayload | Helpdesk ticket lifecycle | 10 |
Each is a structural copy of what the publisher is expected to emit, not a shared type. The four families whose publishers reshaped their contracts to a uniform payload are consumed through these local records.
Contract-coupling consequence
This split produces two different coupling models on one surface.
For the ten shared contracts, a publisher-side change breaks the build, so drift is caught at compile time.
For the 32 events covered by local records, nothing connects the publisher's contract to Notification's copy. A publisher renaming or removing a field compiles cleanly on both sides; the mismatch appears only at runtime as a null or default value after deserialization. Because deserialization is tolerant and the resolver guards on a small number of key fields, a drifted field typically produces an empty template variable rather than an error — a silent degradation.
Deserialization behavior
Parsing is tolerant by design: a payload that fails to deserialize, or whose key identifier is empty, yields a null intent and therefore no notification, recorded with a no-recipient outcome rather than raising. Missing string fields are coalesced to empty values when building template variables.
Classification
Transitional — shared contracts are Implemented; the local-record duplication is a Transitional coupling.
Requires confirmation
Whether the four locally duplicated payload families are intended to move to shared contracts requires confirmation.
Related Articles
See Also
Keywords
- Notification database
- Integration Events
- Draft database documentation
Source References
microservices/src/notification-service/Application/EventNotificationResolver.csmicroservices/src/contracts/Events/IntegrationEvent.csmicroservices/src/notification-service/Messaging/NotificationEventEnvelope.cs
Revision Information
- Status: Draft
- Last reviewed: 2026-07-21
- Review cycle: Quarterly