Aller au contenu

BC-065D — Projection / Realtime Orchestration Boundary

Status: HISTORICAL For the current architecture, see: ./dependances.md, ../runtime/overview.md.

Status

BC-065D completed.

No plugin file changed. No runtime mirror file changed. No Composer change. No runtime sync.

Audit verdict

The Projection / Realtime legacy slice remained mostly dormant, but four mechanical defects were proven inside the slice itself:

  1. EventSubscriberRegistry rejected canonical Platform\Domain\Shared\DomainEvent objects because it imported the wrong legacy namespace.
  2. ProjectionCatalogWiring required Application\Projection\CatalogProjectionWriter, while the actual canonical writer lives under Platform\Application\Projection\CatalogProjectionWriter.
  3. AsyncWorker popped events from the queue but never forwarded them through the realtime pipeline; it only called boot().
  4. RealtimeCatalogRebuilder::boot() re-registered the same handlers on every call, and handleProductEvent() did not accept the canonical aggregateId shape already used by ProductCreatedV2.

Retained structure

Class Role Decision
Projection\EventSubscriberRegistry pure in-memory registry retained
Projection\ProjectionCatalogWiring wiring shell around store + writer + engine retained
Projection\ProjectionEngine placeholder replay-and-dispatch shell retained
Realtime\Async\AsyncEventQueue in-memory queue placeholder retained
Realtime\Async\AsyncWorker thin queue consumer retained
Realtime\RealtimeCatalogRebuilder realtime orchestration shell retained

Mechanical fixes applied

  • registry now accepts canonical Platform\Domain\Shared\DomainEvent
  • projection wiring now accepts the canonical Platform\Application\Projection\CatalogProjectionWriter
  • realtime worker now forwards canonical domain events into the rebuilder instead of only calling boot()
  • realtime rebuilder boot is idempotent
  • realtime rebuilder now supports product id extraction from:
  • productId()
  • aggregateId()
  • public aggregateId

Behavior preserved

  • no SQL changed
  • no payload changed
  • no EventBridge behavior changed
  • no EventPlatform / M12 behavior changed
  • no plugin/runtime entrypoint changed
  • no worker real execution introduced

Remaining debt

  • ProjectionEngine still contains placeholder dispatch logic
  • ProjectionCatalogWiring still builds a legacy engine directly
  • AsyncEventQueue remains an in-memory placeholder rather than a canonical queue port
  • RealtimeCatalogRebuilder still delegates to legacy catalog intelligence/ranking services

These are certification debts, not blockers for BC-065D closure.

BC-065E final certification closes BC-065 without changing that assessment: the remaining debt in this slice is documented as P2 only.