From 3d653666c2cbadf76cdc221da46944511b7b626d Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Sat, 9 May 2026 14:01:38 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20events=20now=20optional=20=E2=80=94=20S?= =?UTF-8?q?tatus=20headers=20+=20conditional=20HTML=20rendering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ADR-015: Status → Optional with scaffold command + behavior note (bus absent means no-op, IJobQueue unaffected) - events-and-jobs.md: prerequisite callout block explaining core-events is optional, how to scaffold, and which features require it - data-flow-explainer.html: note bus is optional in BindProductionContext blurb; add inline comment in code snippet that bus is scaffoldable Co-Authored-By: Claude Sonnet 4.6 --- docs/architecture/data-flow-explainer.html | 3 ++- docs/decisions/adr-015-events-and-jobs.md | 7 ++++++- docs/guides/events-and-jobs.md | 12 ++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/architecture/data-flow-explainer.html b/docs/architecture/data-flow-explainer.html index d096ba8..1574732 100644 --- a/docs/architecture/data-flow-explainer.html +++ b/docs/architecture/data-flow-explainer.html @@ -1703,6 +1703,7 @@ footer .colophon {

blog/di/bind-production.ts

Called from each app's bootstrap (apps/web-next/src/server/bind-production.ts) with the ctx object built once by the aggregator. BindProductionContext is imported from @repo/core-shared/di.

export function bindProductionBlog(ctx: BindProductionContext): void {
+  // bus is optional — present only when @repo/core-events is scaffolded
   const { config, tracer, logger, bus, queue, realtime, realtimeRegistry } = ctx;
   if (blogContainer.isBound(BLOG_SYMBOLS.IArticlesRepository)) {
     blogContainer.unbind(BLOG_SYMBOLS.IArticlesRepository);
@@ -2192,7 +2193,7 @@ footer .colophon {
     
di/bind-production.ts

Production binder

-

bindProduction<F>(ctx: BindProductionContext) — unbinds the mock, rebinds the real Payload-backed impl. The ctx arg carries required fields (tracer, logger, config) and optional cross-cutting deps (bus, queue). Realtime deps (realtime, realtimeRegistry) are also optional — present only when @repo/core-realtime is scaffolded via pnpm turbo gen core-package realtime.

+

bindProduction<F>(ctx: BindProductionContext) — unbinds the mock, rebinds the real Payload-backed impl. The ctx arg carries required fields (tracer, logger, config) and optional cross-cutting deps (queue). Event bus (bus) is also optional — present only when @repo/core-events is scaffolded via pnpm turbo gen core-package events; absent, bus?.subscribe/publish calls are no-ops. Realtime deps (realtime, realtimeRegistry) are also optional — present only when @repo/core-realtime is scaffolded via pnpm turbo gen core-package realtime.

Pros
  • Decouples Payload config from the feature package — boundary stays clean
  • diff --git a/docs/decisions/adr-015-events-and-jobs.md b/docs/decisions/adr-015-events-and-jobs.md index 4b31d2c..ddff950 100644 --- a/docs/decisions/adr-015-events-and-jobs.md +++ b/docs/decisions/adr-015-events-and-jobs.md @@ -1,6 +1,11 @@ # ADR-015 — Cross-feature events and background jobs -**Status:** Accepted +**Status:** Optional — scaffold via `pnpm turbo gen core-package events`. +When absent, `ctx.bus` is undefined and feature binders' `bus?.subscribe/publish` +calls are silent no-ops. Cross-feature event fanout does not operate until +core-events is scaffolded. `IJobQueue` (in `@repo/core-shared/jobs`) and the +`gen event`/`gen job` generators remain fully functional without core-events. + **Date:** 2026-05-08 **Spec:** docs/superpowers/specs/2026-05-08-events-and-jobs-design.md **Plan:** docs/superpowers/plans/2026-05-08-events-and-jobs.md diff --git a/docs/guides/events-and-jobs.md b/docs/guides/events-and-jobs.md index 85f7e8a..3fdfd02 100644 --- a/docs/guides/events-and-jobs.md +++ b/docs/guides/events-and-jobs.md @@ -2,6 +2,18 @@ Walkthrough for adding cross-feature events and background jobs to a feature. For the architectural rationale, see [ADR-015](../decisions/adr-015-events-and-jobs.md) and [the full spec](../superpowers/specs/2026-05-08-events-and-jobs-design.md). +> **Prerequisite — `@repo/core-events` is optional.** +> The event bus (`IEventBus`, `InMemoryEventBus`, `PayloadJobsEventBus`) lives +> in `@repo/core-events`, which ships as a scaffoldable package rather than a +> permanent fixture. If `packages/core-events/` does not exist in your repo, +> run `pnpm turbo gen core-package events` first, then wire the bus into +> `apps/web-next/src/server/bind-production.ts` as described in the generator's +> next-steps output. +> +> Background jobs (`IJobQueue`, `gen job`) work without core-events — they only +> require `@repo/core-shared/jobs`. Cross-feature event fanout (`gen event +> consume`) additionally requires core-events. + The three rules to keep in mind: - **E0** — Events are for cross-feature decoupling. In-feature reactions are direct use-case calls.