Platform Events for Modules¶
This contract defines the platform → modules direction. It is an agreed architecture;
the generic outbound bridge is not yet enabled in production.
Processing model¶
Platform business logic
→ EventBus::emit(internal_name, typed_payload, event_code)
→ MoleculerEventBridge
→ allowed-type and event-code check
→ explicit safe JSON formatter
→ external event-name mapping
→ MoleculerBroker::emit(event_name, data)
→ subscribed modules
The existing typed C++ EventBus remains the internal source of platform events. The
bridge is an adapter and policy boundary; it is not a second business event system.
Event name¶
For ordinary record lifecycle events, the external name is derived from the payload type and event code:
<entity>.<operation>
| Payload type | Entity |
|---|---|
TradeRecord |
trade |
AccountRecord |
account |
CustomerRecord |
customer |
| Event code | Operation |
|---|---|
EV_RECORD_ADD |
add |
EV_RECORD_UPDATE |
update |
EV_RECORD_DELETE |
delete |
Examples:
TradeRecord + EV_RECORD_ADD → trade.add
TradeRecord + EV_RECORD_UPDATE → trade.update
AccountRecord + EV_RECORD_UPDATE → account.update
CustomerRecord + EV_RECORD_DELETE → customer.delete
A specialised mapping is allowed when a domain event is not a CRUD operation. For
example, a margin-state transition can map to account.margin_state. Every specialised
mapping is an explicit part of the public contract.
The internal EventBus name is not used as an automatic external API name. The payload
type and event code define the external semantic contract.
Explicit allow list¶
A type being present in EventBus::EventPayload does not make it public. The bridge
publishes only types for which an external mapping and formatter were explicitly added.
If the type or event code is unknown, incompatible or not enabled, the bridge drops the event and records the reason. Adding a new type to the internal variant must never expose it automatically.
Quotes are never published through this bridge.
Safe formatter¶
Each public payload type has a dedicated formatter. The formatter creates a new JSON object with an explicit field list; it must not serialise the complete internal C++ record automatically.
A formatter must:
- expose only fields declared by the external contract;
- omit internal implementation fields;
- omit or mask personal and sensitive data;
- preserve stable field names and JSON types;
- validate the combination of payload type and event code;
- version incompatible schema changes.
Changing an internal C++ structure must not silently change the external event schema.
Common envelope¶
Every published event contains common metadata and event-specific data:
{
"event_id": "0192f7d7-8bd5-7e1a-b6cb-0f1e37d1ad11",
"event_code": 1,
"occurred_at": 1789080000,
"schema_version": 1,
"data": {}
}
| Field | Type | Meaning |
|---|---|---|
event_id |
string | Unique tracing and deduplication identifier |
event_code |
integer | Original platform event semantic code |
occurred_at |
integer | Unix time when the domain event occurred |
schema_version |
integer | Version of this event-family JSON schema |
data |
object | Explicitly formatted public fields |
A formatter may add resource, brand or routing identifiers only when those fields are approved for that event family.
Delivery semantics¶
MoleculerBroker::emit() routes an event to remote nodes that announced a matching event
subscription in Moleculer INFO. No subscriber is a valid state and is not a business error
in the trading core.
The first contract does not promise durable storage, replay or exactly-once delivery.
Consumers should use event_id for deduplication when their processing can be retried.
Critical operations that require an acknowledgement must use actions.
The bridge must use a bounded queue and expose at least:
- published event count by event name;
- rejected event count by reason;
- formatter and NATS publish errors;
- queue overflow count;
- queue depth and handler latency.
Transition events such as margin-call level changes must not be silently coalesced in a way that loses a real state transition.