diff --git a/AGENTS.md b/AGENTS.md index b8244f3..cf85d94 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -321,24 +321,21 @@ Each app (`web-next`, `web-tanstack`, `cms`) imports both binders per feature an ```typescript // apps/web-next/src/server/bind-production.ts +// Slim default template — no optional packages scaffolded yet. +// After running e.g. `pnpm turbo gen core-package events`, the full +// IEventBus type can be plugged via the generic args +// `BindProductionContext` and the bus/queue construction +// (resolveEventsAndJobsProduction) wires back in per the printed next-steps. import type { BindProductionContext, BindContext } from "@repo/core-shared/di"; -import type { IEventBus } from "@repo/core-events"; -import type { IRealtimeBroadcaster, IRealtimeHandlerRegistry } from "@repo/core-realtime"; -export async function bindAllProduction(deps: BindAllDeps): Promise { +export async function bindAllProduction(): Promise { const { tracer, logger } = resolveInstrumentation(); - const { bus, queue } = await resolveEventsAndJobsProduction(); const resolvedConfig = await config; - const { realtime, realtimeRegistry } = deps; - const ctx: BindProductionContext = { + const ctx: BindProductionContext = { config: resolvedConfig, tracer, logger, - bus, - queue, - realtime, - realtimeRegistry, }; bindProductionAuth(ctx); @@ -348,10 +345,8 @@ export async function bindAllProduction(deps: BindAllDeps): Promise { bindProductionMedia(ctx); } -export async function bindAllDevSeed(deps: BindAllDeps): Promise { +export async function bindAllDevSeed(): Promise { const { tracer, logger } = resolveInstrumentation(); - const { bus, queue } = resolveEventsAndJobsDevSeed(); - const { realtime, realtimeRegistry } = deps; const ctx: BindContext = { tracer, logger, bus, queue, realtime, realtimeRegistry, diff --git a/docs/scaffolding/core-package-generator.md b/docs/scaffolding/core-package-generator.md index a4ebd57..115bcea 100644 --- a/docs/scaffolding/core-package-generator.md +++ b/docs/scaffolding/core-package-generator.md @@ -24,8 +24,6 @@ The generator emits the package files, updates consuming-app config (e.g. `apps/ | `trpc` | tRPC server setup | Phase 5 | | `ui` | Design-system package | Phase 6 | -(Until Phases 3-6 land, the generator will list an empty choices array and reject any selection.) - ## Verifying an existing project If your project already has a core-* package and you want to verify the generator's template hasn't drifted from the shipped source, use the byte-identical reconstruction snapshot: diff --git a/packages/core-shared/src/di/bind-protocols.test.ts b/packages/core-shared/src/di/bind-protocols.test.ts index 2d2bbec..90a5783 100644 --- a/packages/core-shared/src/di/bind-protocols.test.ts +++ b/packages/core-shared/src/di/bind-protocols.test.ts @@ -5,6 +5,14 @@ import type { RealtimeRegistryProtocol, } from "./bind-protocols"; +// Protocol-shape tests. These verify each protocol type EXPORTS the +// expected method names. Full assignability of `IEventBus` / +// `IRealtimeBroadcaster` / `IRealtimeHandlerRegistry` to their respective +// protocols is verified at the optional-package level — when those packages +// are scaffolded back via `pnpm turbo gen core-package `, the +// `extends`-link in their interface declarations forces a typecheck +// failure if the protocol surface ever drifts. + describe("EventBusProtocol", () => { it("requires publish(event, payload) and subscribe(event, consumer, handler)", () => { type Bus = EventBusProtocol; diff --git a/packages/marketing-pages/src/di/bind-dev-seed.ts b/packages/marketing-pages/src/di/bind-dev-seed.ts index 5fb97bb..a563570 100644 --- a/packages/marketing-pages/src/di/bind-dev-seed.ts +++ b/packages/marketing-pages/src/di/bind-dev-seed.ts @@ -139,7 +139,8 @@ export async function bindDevSeedMarketingPages(ctx: BindContext): Promise // // onAuthUserSignedUpHandler subscription — generated, edit the handler file (not this block) for behavior. - // queue is optional: guard so the handler is only bound when core-jobs is wired (Phase 3+). + // bus is optional: when @repo/core-events is not scaffolded, ctx.bus is undefined and the handler is not bound. + // queue (IJobQueue) is in core-shared and always provided; the inner if (queue) below is belt-and-suspenders. if (queue) { const wrappedAuthUserSignedUp = withSpan( tracer, diff --git a/packages/marketing-pages/src/di/bind-production.ts b/packages/marketing-pages/src/di/bind-production.ts index 4447753..de21601 100644 --- a/packages/marketing-pages/src/di/bind-production.ts +++ b/packages/marketing-pages/src/di/bind-production.ts @@ -129,7 +129,8 @@ export function bindProductionMarketingPages(ctx: BindProductionContext): void { // // onAuthUserSignedUpHandler subscription — generated, edit the handler file (not this block) for behavior. - // queue is optional: guard so the handler is only bound when core-jobs is wired (Phase 3+). + // bus is optional: when @repo/core-events is not scaffolded, ctx.bus is undefined and the handler is not bound. + // queue (IJobQueue) is in core-shared and always provided; the inner if (queue) below is belt-and-suspenders. if (queue) { const wrappedAuthUserSignedUp = withSpan( tracer, diff --git a/turbo/generators/config.test.ts b/turbo/generators/config.test.ts index 45a0e3e..025b026 100644 --- a/turbo/generators/config.test.ts +++ b/turbo/generators/config.test.ts @@ -17,6 +17,8 @@ describe("core-package generator", () => { expect(prompts[0]!.name).toBe("name"); expect(prompts[0]!.choices).toContain("realtime"); expect(prompts[0]!.choices).toContain("events"); + expect(prompts[0]!.choices).toContain("trpc"); + expect(prompts[0]!.choices).toContain("ui"); }); });