Commit Graph

274 Commits

Author SHA1 Message Date
1e8b3f2364 docs: BindContext binder shape across architecture + per-feature AGENTS 2026-05-09 12:49:55 +02:00
3911405102 refactor(media): binders take BindContext arg 2026-05-09 12:44:30 +02:00
a439038748 refactor(navigation): binders take BindContext arg 2026-05-09 12:43:22 +02:00
fe6c41b69d refactor(marketing-pages): binders take BindContext arg 2026-05-09 12:42:29 +02:00
fe85976440 refactor(blog): binders take BindContext arg 2026-05-09 12:40:58 +02:00
ab8ca08307 refactor(auth): binders take BindContext arg 2026-05-09 12:39:50 +02:00
f4942098f1 feat(core-realtime): IRealtimeHandlerRegistry extends RealtimeRegistryProtocol 2026-05-09 12:37:38 +02:00
ebcce46681 feat(core-realtime): IRealtimeBroadcaster extends RealtimeBroadcasterProtocol 2026-05-09 12:37:26 +02:00
07fa35cd0b feat(core-events): IEventBus extends EventBusProtocol 2026-05-09 12:36:38 +02:00
5ba11e3405 feat(core-shared): expose ./di subpath export 2026-05-09 12:36:20 +02:00
1d160e7e22 feat(core-shared): BindContext + BindProductionContext types 2026-05-09 12:36:06 +02:00
b5a9d1fe9d feat(core-shared): bind-protocols (event bus / realtime / realtime registry) 2026-05-09 12:35:48 +02:00
6a0ac63bb9 fix(realtime): CI gate fixes surfaced by Phase 11 smoke tests
- no-direct-socket-io: extend allowlist to cover apps/*/src/**/*.test.ts so
  the realtime-ping e2e integration test can import socket.io/socket.io-client
  directly; add two valid test cases to keep the rule's own test suite green
- tsconfig.json (root): add root-level tsconfig with experimentalDecorators +
  emitDecoratorMetadata and no "include" so tsx 4.21.0's createFilesMatcher
  resolves decorator config for all workspace packages, not just web-next's
  own source tree
- web-next dev script: pass TSX_TSCONFIG_PATH=../../tsconfig.json so the
  custom Node server uses the root tsconfig for all modules it loads
- next.config.mjs: add @repo/core-events and @repo/core-realtime to
  transpilePackages so Next.js webpack can resolve their workspace source files
- server.ts: replace static authContainer import with a dynamic import inside
  IRealtimeAuthenticator.authenticate so Inversify decorators are applied only
  after bindAll() has already populated the container

All CI gates pass: lint (0 errors), typecheck, 20 tests (incl. realtime-ping
e2e), boundaries (0 issues).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:32:43 +02:00
cbac166782 test(core-realtime): unit cover registerChannel + listChannels
- Add 4 new test cases to RealtimeHandlerRegistry test suite
- registerChannel stores outbound-only descriptors distinct from inbound
- listChannels() includes both inbound (from register) and outbound-only channels
- Validates backward-compat guarantee and re-registration behavior

Test count: 4 → 8 in realtime-handler-registry.test.ts
All 35 tests in core-realtime pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:42:35 +02:00
b9caf605d2 test(web-next): e2e realtime-ping (4 checkpoints) 2026-05-09 00:39:44 +02:00
2351ca6249 feat(web-next): register realtime-ping inbound (env-gateable) 2026-05-08 23:20:58 +02:00
90ef577b9d feat(core-realtime): realtime-ping proof-of-life channel pair 2026-05-08 23:19:52 +02:00
9b7878a623 feat(navigation): bind binders accept (realtime, realtimeRegistry) params
Extend bindProductionNavigation and bindDevSeedNavigation to 7-arg signatures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:41:16 +02:00
579c5911fd feat(marketing-pages): bind binders accept (realtime, realtimeRegistry) params
Extend bindProductionMarketingPages and bindDevSeedMarketingPages to 7-arg signatures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:41:13 +02:00
f85b0891ee feat(media): bind binders accept (realtime, realtimeRegistry) params
Some checks failed
CI / typecheck + lint + boundaries + test + build (push) Has been cancelled
CI / Playwright e2e (push) Has been cancelled
CI / Storybook smoke tests (push) Has been cancelled
Sentry PII guard (R31) / pii-guard (push) Has been cancelled
Extend bindProductionMedia and bindDevSeedMedia to 7-arg signatures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:41:10 +02:00
1f12e6af12 feat(blog): bind binders accept (realtime, realtimeRegistry) params
Extend bindProductionBlog and bindDevSeedBlog to 7-arg signatures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:41:07 +02:00
7e1d2d5c4b feat(auth): bind binders accept (realtime, realtimeRegistry) params
Extend bindProductionAuth and bindDevSeedAuth to 7-arg signatures.
Fix RecordingRealtimeBroadcaster scope type to structurally match ChannelScope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:41:04 +02:00
c882614153 test(core-eslint): extend anchor-presence guard for realtime anchors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:07:21 +02:00
f5b0e8e6ae chore(navigation): add // <gen:realtime-*> anchor comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:07:08 +02:00
2939b94302 chore(marketing-pages): add // <gen:realtime-*> anchor comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:06:45 +02:00
4fd95921f0 chore(media): add // <gen:realtime-*> anchor comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:06:14 +02:00
8367cb184e chore(blog): add // <gen:realtime-*> anchor comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:05:51 +02:00
03a0900688 chore(auth): add // <gen:realtime-*> anchor comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:05:27 +02:00
122a81b2ca feat(core-eslint): rule no-realtime-handler-reexport
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:01:03 +02:00
77467de702 feat(core-eslint): rule no-direct-socket-io
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 21:59:52 +02:00
928357f221 feat(core-testing): RecordingRealtimeBroadcaster (local-type-alias pattern) 2026-05-08 21:56:18 +02:00
228cfb57c0 fix(core-realtime): address Phase 2 code review (typing, error handling, params)
- Type socket.data.user via AppSocketData/AppSocket generics (no more any)
- Wrap Gate 1 authenticator call in try/catch so exceptions reject the
  connection with connect_error instead of being swallowed
- Fix Gate 3 userScoped channel authorize: derive params.userId from the
  authenticated socket user so owner-inbound is accepted
- Await io.close(callback) in stop() to ensure full shutdown
- Remove unused httpServer field from constructor (io already holds the ref)
- Extract CHANNEL_ROOM_PREFIX/channelRoom helper to channel-room.ts;
  replace three `ch:${name}` magic strings; re-export from index
- Add JSDoc to ChannelScope explaining userScoped params/template convention
- Fix "allows subscribe + invokes handler with ctx" test: hoist received
  outside beforeEach and assert ctx shape
- New test: rejects connection when authenticator throws
- New test: userScoped channel accepts inbound from owner, rejects from anon
2026-05-08 21:52:52 +02:00
964fabf796 fix(core-realtime): remove unused PLACEHOLDER var and ClientSocket import (lint) 2026-05-08 21:16:44 +02:00
d4a3f95938 feat(core-realtime): public barrel 2026-05-08 21:16:22 +02:00
2939ff8bb5 feat(core-realtime): SocketIORealtimeServer (4 lifecycle gates) 2026-05-08 21:16:03 +02:00
9d04bdc65b feat(core-realtime): SocketIORealtimeBroadcaster 2026-05-08 21:15:07 +02:00
86b9418758 feat(core-realtime): IRealtimeServer interface 2026-05-08 21:14:43 +02:00
5e57c66140 feat(core-realtime): InMemoryRealtimeBroadcaster (test/dev impl) 2026-05-08 21:14:33 +02:00
6c5484b874 feat(core-realtime): RealtimeHandlerRegistry 2026-05-08 21:14:11 +02:00
f072435024 feat(core-realtime): authorize function (4 scope kinds) 2026-05-08 21:13:48 +02:00
0771601571 feat(core-realtime): channel-template matcher (placeholder extraction) 2026-05-08 21:13:18 +02:00
691b4942d5 feat(core-realtime): IRealtimeAuthenticator interface 2026-05-08 21:12:56 +02:00
caf86abbe5 feat(core-realtime): IRealtimeHandler + IInboundDescriptor types 2026-05-08 21:12:47 +02:00
795511b5b3 feat(core-realtime): IRealtimeBroadcaster interface + symbol registry 2026-05-08 21:12:36 +02:00
7e922bc406 feat(core-realtime): RealtimeChannelDescriptor + defineRealtimeChannel 2026-05-08 21:12:24 +02:00
1a0e3c20ff chore(core-realtime): align scaffold style with core-events (review polish) 2026-05-08 21:09:50 +02:00
fd76aa445d chore(core-eslint,turbo): tag @repo/core-realtime as core
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 20:59:01 +02:00
bbdb456aa0 chore(core-realtime): scaffold package
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 20:58:05 +02:00
5a2234f7ad docs: refresh per-package AGENTS.md + di-explainer to current binders
Six per-package AGENTS.md tables and the di-explainer wiring trace all
showed pre-ADR-014 binder shapes. Refreshed to the post-ADR-015
reality:

- Per-package "Public exports" tables now show the
  (config, tracer, logger, bus, queue) production signature and the
  (tracer, logger, bus, queue) dev-seed companion. auth and
  marketing-pages also list their newly-public ./di/container,
  ./di/symbols, and (marketing-pages only) ./services/mailer +
  ./services/recording-mailer subpaths.
- di-explainer's wiring trace adds the resolveEventsAndJobs* step in
  bindAll(), the (config, tracer, logger, bus, queue) binder
  signature, and the // <gen:event-handlers> / // <gen:jobs>
  injection sites.

No code change; pre-existing AGENTS.md staleness predates ADR-014 +
ADR-015 — this commit catches both up.
2026-05-08 17:51:35 +02:00
a98e41d080 chore: workspace green check (Task 56)
Three issues uncovered by the full pnpm typecheck/test/boundaries pass
and resolved here:

- core-testing was importing IEventBus / IJobQueue from core-events /
  core-shared, creating two boundary violations (tooling → core) and a
  build-graph cycle. Inlined the type aliases (mirroring how
  RecordingTracer / RecordingLogger handle ITracer / ILogger).
  recording-event-bus.test.ts replaces defineEvent() with an inline
  descriptor literal so no runtime import is needed either. core-events
  and core-shared are removed from core-testing dependencies.

- turbo.json: typecheck and test no longer dependsOn ^typecheck / ^build.
  Each package's tsc / vitest resolves cross-package types via
  node_modules independently, and dropping the topological dep avoids the
  spurious cycle warning that appeared once core-testing started
  importing core-events / core-shared.

- turbo.json: feature.dependencies.allow gains "feature". Cross-feature
  event flow (ADR-015) requires a consumer feature to import the
  publisher's event contract directly. The dangerous form (importing
  the publisher's handler/use-case/repo) is still blocked by E1's
  no-handler-reexport ESLint rule and the missing public exports.

- TaskConfig<"slug-string"> → TaskConfig<{ input; output }> in the gen
  job task template (and the shipped send-welcome-email.task.ts) since
  runtime-generated slugs aren't keys of TypedJobs['tasks'].
2026-05-08 17:21:47 +02:00