Learn-skills.dev eventing-hub
Event-sourcing and EventBus directives for Black-Tortoise, covering structured event schemas, append-before-publish flow, causality/id rules, and safe subscribers; use when touching src/app/eventing, EventBus, or any event handlers/projections.
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/7spade/black-tortoise/eventing-hub" ~/.claude/skills/neversight-learn-skills-dev-eventing-hub && rm -rf "$T"
manifest:
data/skills-md/7spade/black-tortoise/eventing-hub/SKILL.mdsource content
Eventing Hub Master Guide
Intent
Describe event contracts, persistence/publish order, and consumer safety for the shared EventBus described in
src/app/eventing/AGENTS.md and .github/instructions/20-ddd-event-sourcing-copilot-instructions.md.
Event Schema
- Declare events with a Type, Payload, Metadata, and Semantics structure; keep payloads immutable and document any allowed mutations in the metadata.
- Use a
to tie related events, and assign acorrelationId
that points to the triggering event (null only for root events).causationId - Emit only typed events from the Aggregates/Application services; do not publish raw DTOs or Firebase objects.
Append → Publish → React
- Persist every outcome (Append) before invoking the
publish step; never wrap append/publish inEventBus
or parallel flows to avoid causality gaps.Promise.all - After the append promise resolves, publish the event and let downstream stores/projections react via the global
singleton.EventBus - Reactions should be limited to simple projections or side effects; long-running work belongs to dedicated use cases handled by the Application layer.
Causality Tracking & Immutability
- Maintain causation/correlation IDs for every published event; log them for tracing and include them in metadata for audit tooling.
- Treat emitted events as read-only facts; consumers may inspect but must never mutate payload or metadata objects.
- Use
or deep copies when broadcasting to ensure immutability guarantees reach all subscribers.Object.freeze()
Safe Subscriptions
- Convert the RxJS stream behind
into signals at the Application boundary usingEventBus
before exposing data to Presentation stores.toSignal() - Guard subscriptions with
or signal-based cleanup so that event handlers do not leak after a component/store is destroyed.takeUntilDestroyed() - Prefer
stores for reacting to events; their@ngrx/signals
handlers should callwithMethods
based on event payloads rather than mutating the store directly.patchState
Validation & Monitoring
- Validate payload schemas before append, using domain value objects to enforce invariants (Domain layer) and rejecting invalid data early.
- Emit audit events when Append or Publish steps fail so
trackers capture the problem context.docs/AUDIT-* - Feed causality IDs into any observability tooling to verify the Append→Publish→React chain during CI or runtime tracing.