Story: Codegen: generate per-entity NATS event-mapping registrar

Table of Contents

This page documents a story in Sprint 22. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Every domain entity's live NATS change-event pipeline (Postgres NOTIFY channel -> in-process event_bus -> re-published NATS event) is currently wired by hand in each component's service/src/app/application.cpp: one #include, one register_mapping<T_changed_event>() call, and one event_bus.subscribe<T_changed_event>() lambda per entity, scattered across three places. This is 100% mechanical (event type, channel name, and entity name are already known from the entity's codegen model) and has already caused a missed-wiring regression (purpose_type, and previously party_type). Extend codegen to emit a per-entity event-mapping registration function into the same generated <entity>_registrar.hpp/cpp pair already produced for request/response handlers, and add a small service-layer registrar aggregator (mirroring ores.refdata.core::messaging::registrar::register_handlers) so application.cpp collapses each per-entity block down to a single call.

Status

Field Value
State DONE
Parent sprint Sprint 22
Now Shipped in PR #1459: 6/16 refdata entities migrated to the generated registrar; pattern documented; remaining 10 deferred to a capture.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-06

Acceptance

  • Codegen emits register_<entity>_event_mapping(event_source, event_bus, nats) into the existing generated <entity>_registrar.hpp/cpp pair for every domain_entity model with eventing enabled.
  • A new service-layer registrar aggregator (e.g. ores::refdata::service::messaging::event_registrar or similar, colocated with application.cpp) calls each generated per-entity function; application.cpp's entity-change-event pipeline section collapses to a single aggregator call, matching the existing register_handlers call-site pattern.
  • purpose_type and all other refdata entities currently wired by hand in application.cpp are migrated to the generated path with zero loss of functionality; cross-client NATS eventing verified working for at least purpose_type.
  • Pattern documented (recipe or knowledge doc) so other components (trading, marketdata, etc.) can adopt the same generated registrar without hand-wiring their own application.cpp.

Tasks

Task State Start End Description
Generate per-entity NATS event-mapping registrar DONE 2026-07-07 2026-07-08 Extend codegen to emit register_<entity>_event_mapping into the generated <entity>_registrar.hpp/cpp pair, add a service-layer aggregator, and migrate application.cpp's hand-wired entity change-event pipeline to call it.

Decisions

  • The generated per-entity registrar lives in the .service layer (new component_service=/=component_service_dir template variables), not .core like the request/response sub-registrar, because the eventing pipeline depends on ores.eventing.core (postgres_event_source, event_bus), which no .core component links.
  • Only 6 of 16 currently hand-wired refdata entities were migrated (book, business_day_convention_type, country, currency, party_type, purpose_type); the other 10 have stale nats-eventing output (a breaking id-field rename risk) and stay hand-wired pending a follow-up. See Migrate remaining refdata entities to generated event-mapping registrar.
  • Pattern documented in How do I wire an entity into live NATS eventing?.

Out of scope

  • Migrating the other 10 refdata entities (tracked separately, see Decisions).
  • Migrating other components (trading, marketdata, etc.) to the pattern.
  • Removing the remaining per-component duplicates of publish_entity_event (ores.analytics, ores.compute, ores.trading, ores.workspace) — only ores.refdata's copy was removed.

Emacs 29.3 (Org mode 9.6.15)