Commit Graph

333 Commits

Author SHA1 Message Date
b672506c30 chore(media): add // <gen:*> anchor comments for event/job generators
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:47:04 +02:00
2506c2676b chore(blog): add // <gen:*> anchor comments for event/job generators
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:46:31 +02:00
73bfb22fe2 chore(auth): add // <gen:*> anchor comments for event/job generators
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:23:52 +02:00
5b766242be feat(core-eslint): rules E1 (no handler re-exports) and J (no direct payload.jobs)
Implements spec § 7 via no-restricted-syntax built-in selectors — mirrors
the R40 no-restricted-imports precedent; no custom plugin required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:18:14 +02:00
1357e45f55 feat(core-testing): RecordingEventBus
Adds RecordingEventBus implementing IEventBus for use in unit tests.
Validates payloads via the descriptor schema, records all publish calls,
and delivers events to subscribed handlers synchronously in subscription order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:05:34 +02:00
590b92f190 feat(core-testing): RecordingJobQueue
Adds RecordingJobQueue implementing IJobQueue for use in unit tests.
Records all enqueue calls with taskSlug/input/options and returns
synthetic incrementing jobIds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 12:04:22 +02:00
05f0b02856 docs(core-events): clarify subscribe consumerFeature + failFast drop
Code-quality review nits: IEventBus.subscribe docstring said "debug
tag" but InMemoryEventBus actually ignores the param entirely. Also
add a comment to InMemoryEventBus.publish noting that under failFast
only the first rejection rethrows; other failures are intentionally
dropped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:02:45 +02:00
430c831743 feat(core-events): public barrel
Export EventDescriptor, defineEvent, IEventBus, EventHandler,
CORE_EVENTS_SYMBOLS, InMemoryEventBus, InMemoryEventBusOptions, and
PayloadJobsEventBus from src/index.ts. All typecheck, test (11 tests),
and lint checks pass. turbo boundaries: 454 files, no issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:58:07 +02:00
ef451de437 feat(core-events): PayloadJobsEventBus (fan-out via IJobQueue)
TDD: red (test-only), then green. PayloadJobsEventBus validates before
enqueueing, names tasks __events.<event>.<consumer> deterministically, and
enqueues one task per subscriber via Promise.all. 3 new tests (11 total).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:57:48 +02:00
cb785b600a feat(core-events): InMemoryEventBus with failFast option
TDD: red (test-only), then green. InMemoryEventBus validates payloads via
descriptor.schema before fanout, delivers to all handlers via Promise.allSettled,
swallows handler errors by default, and rethrows first error when failFast:true.
5 new tests (8 total passing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:57:19 +02:00
3da93efb89 feat(core-events): IEventBus interface + symbol registry
IEventBus defines publish<T> and subscribe<T> with consumerFeature parameter.
CORE_EVENTS_SYMBOLS.IEventBus uses Symbol.for for cross-module identity.
Typecheck passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:56:52 +02:00
ba3b6c9af6 feat(core-events): EventDescriptor + defineEvent
TDD: red (test-only), then green. defineEvent(name, schema) returns a typed
EventDescriptor<TName, TSchema>. Also added @repo/core-testing to devDeps
(required for nodeVitestConfig's setupFiles). 3 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:56:37 +02:00
f99a307f72 chore(core-eslint,turbo): tag @repo/core-events as core
The existing turbo.json boundaries use tag names (not package names), and
the core-eslint boundaries config uses the packages/core-* glob. Both already
cover @repo/core-events through its turbo.json "tags": ["core"] declaration.
pnpm turbo boundaries confirms: 445 files in 18 packages, no issues found.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:55:44 +02:00
f94128943a chore(core-events): scaffold package
Create @repo/core-events package skeleton with package.json, tsconfig.json,
vitest.config.ts (using mergeConfig with nodeVitestConfig), eslint.config.js,
turbo.json (tagged core), and AGENTS.md. Register workspace via pnpm install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:55:28 +02:00
2f52a11db8 feat(core-shared/jobs): public barrel via @repo/core-shared/jobs subpath 2026-05-08 11:36:29 +02:00
23a1faa002 feat(core-shared/jobs): PayloadJobQueue 2026-05-08 11:36:12 +02:00
b96cff34ba feat(core-shared/jobs): InMemoryJobQueue with register() 2026-05-08 11:35:50 +02:00
a2a83e1cf2 feat(core-shared/jobs): symbol registry 2026-05-08 11:35:25 +02:00
cf32175684 feat(core-shared/jobs): IJobQueue interface 2026-05-08 11:35:15 +02:00
e85c89144b feat(core-shared): add ./jobs subpath export 2026-05-08 11:33:05 +02:00
892f924603 docs: surface turbo gen feature in AGENTS.md and CLAUDE.md
Wires the existing turbo gen feature generator into AGENTS.md (Adding
a Feature section, Key Commands, Specification & Guides) and
CLAUDE.md (Quick Start, Read First). Adds a fast-path callout at the
top of the manual walkthrough in docs/guides/adding-a-feature.md
pointing at scaffolding-a-feature.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:30:10 +02:00
c2a32363a8 docs(plan): bring production-bus task auto-registration into scope
gen event consume now emits a second file: an __events-<publisher>-
<event>.task.ts Payload task that delegates to the consumer's
container-resolved wrapped handler. The bind block also binds the
wrapped handler into the per-feature container by symbol so the
task can resolve it. With this, PayloadJobsEventBus is fully wired
end-to-end with no manual per-event task hand-write required.
Removes the corresponding Known Follow-up item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:28:25 +02:00
42fb3996d3 docs(plan): events and jobs implementation plan
56 bite-sized tasks across 9 phases implementing the spec at
docs/superpowers/specs/2026-05-08-events-and-jobs-design.md:
core-shared/jobs (IJobQueue + 2 impls), core-events package
(IEventBus + 2 impls), recording test helpers, two ESLint rules,
existing-feature anchor retrofit (5 features × 6 anchors), bindAll
bus/queue swap, three Plop generators with anchor-comment protocol,
end-to-end proof-of-life (sign-up → welcome email), and the full
documentation set (ADR-015 + new guide + AGENTS/CLAUDE/scaffolding
updates). Self-review caught and fixed one type-inconsistency
(3-arg subscribe) and explicitly deferred the production task-
registration gap. TDD-ordered with one commit per task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:20:19 +02:00
cf41d11eff docs(spec): cross-feature events and background jobs design
Long-form design for a future ADR-015. Defines IEventBus (new
@repo/core-events) and IJobQueue (@repo/core-shared/jobs); the bind/swap
rules; the events/, events/handlers/, jobs/, integrations/cms/jobs/
folder layout; the on-<publisher>-<event-kebab>.handler.ts naming rule;
the span+capture sandwich extension with op: "event-handler" and
op: "job"; three new ESLint rules; RecordingEventBus and RecordingJobQueue
for tests; pnpm turbo gen event {publish|consume} and gen job generators
plus the // <gen:*> anchor-comment protocol; and the existing-feature
retrofit. Status: draft pending user review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:43:53 +02:00
72d5513916 chore(tsconfig): migrate off deprecated baseUrl
TypeScript 6 deprecates `baseUrl` in favor of resolving `paths`
relative to the file that defines them. Earlier commit (bde40e4)
silenced the warning via `ignoreDeprecations`; this commit does
the actual migration so the warning goes away on its merits.

Changes:

1. tsconfig.base.json: drop `baseUrl: "."`. Add an explicit `./`
   prefix to every `paths` entry so they resolve relative to the
   base config's location (the repo root) — same behavior as
   before, but no baseUrl needed. (TypeScript requires path entries
   to be relative or absolute when baseUrl is absent; bare paths
   like "packages/..." are not allowed.)
2. apps/web-next/tsconfig.json: drop baseUrl. The `@/*` mapping's
   target was already "./src/*" — relative-from-tsconfig-file is
   the new default, so no other change.
3. apps/cms/tsconfig.json: same — drop baseUrl, paths already use
   "./" prefix.
4. apps/storybook/tsconfig.json: same.
5. apps/web-tanstack/tsconfig.json: same.

Generator templates (turbo/generators/templates/feature/tsconfig.json.hbs)
already omit baseUrl, so future-generated features inherit the new
posture.

Reverts the ignoreDeprecations setting added in bde40e4 — no longer
needed.

Verified:
- pnpm typecheck 14/14
- pnpm lint 15/15
- pnpm test 26/26

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:44:00 +02:00
bde40e4ade chore(tsconfig): silence baseUrl-deprecation warning via ignoreDeprecations
TypeScript 6 deprecates `baseUrl` in favor of resolving `paths`
relative to the tsconfig file's directory. The repo's path mappings
in tsconfig.base.json currently rely on baseUrl: "." to resolve
"packages/<feature>/src/index.ts" entries against the repo root,
and four app tsconfigs (web-next, cms, web-tanstack, storybook) use
baseUrl: "." for their own "@/*" → "./src/*" mappings.

Migrating away from baseUrl is a separate cleanup — for now, set
"ignoreDeprecations": "6.0" in the base config so the warning
clears across every config that extends it (extends merges
compilerOptions). This is exactly what TypeScript's own docs
recommend for projects that intend to keep the option until 7.0.

Verified: pnpm typecheck 14/14, pnpm lint 15/15.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:41:20 +02:00
302b0b860c fix(turbo-gen): add local eslint config + package.json for generators dir
The IDE was reporting eslint errors on turbo/generators/config.ts and
on the generated package because there's no eslint config at the repo
root — when eslint walks up from turbo/generators/, it never finds
one. The CLI didn't surface this (eslint silently exited fine on
files it couldn't config), but the IDE eslint daemon did.

- turbo/generators/eslint.config.js extends @repo/core-eslint/base
  and ignores templates/** (the .hbs partials contain {{...}}
  placeholders that aren't valid TS — never lint them).
- turbo/generators/package.json declares "type": "module" so Node
  doesn't warn about CJS-vs-ESM ambiguity when loading the eslint
  config.

Verified end-to-end:
- `npx eslint . -p tsconfig.json` clean in turbo/generators/.
- `pnpm turbo gen feature --args widgets Widget widgets` →
  pnpm install → @repo/widgets passes lint, typecheck, and 25/25
  tests across 9 files.
- packages/widgets cleaned up before commit; not checked in.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:39:54 +02:00
bec10fb171 fix(turbo-gen): annotate answers param + add tsconfig for generators dir
Two diagnostics from the IDE on turbo/generators/config.ts:

1. `Cannot find module '@turbo/gen'` — there was no tsconfig in
   turbo/generators/, so the IDE was opening config.ts in loose mode
   without proper module resolution context. Added a small
   tsconfig.json that extends tsconfig.base, sets NodeNext module
   resolution, and includes only ./**/*.ts (templates excluded).

2. `Parameter 'answers' implicitly has an 'any' type` — annotated
   the printNextSteps custom-action function param as
   `Record<string, unknown>` (Plop's runtime answers shape). The
   inner cast to the typed Answers shape was already in place.

`npx tsc --noEmit -p turbo/generators/tsconfig.json` is now clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:11:40 +02:00
019d4866a0 feat(turbo): turbo gen feature generator (Phase 1, single-entity)
Adds `pnpm turbo gen feature` to scaffold a Lazar-conformant feature
package matching the navigation reference shape: entity + Zod schema,
single use case (`get<Entity>`), controller, mock + Payload-stub real
repository (with span + capture), DI module/container/symbols, and tRPC
router with full BAD_REQUEST/NOT_FOUND error mapping. The generated
`bind-production.ts` and `bind-dev-seed.ts` compose the post-R44
`withSpan(tracer, opts, withCapture(logger, tags, factory(deps)))`
sandwich at bind time.

Verified by generating a sample `packages/example/` feature and running
`pnpm --filter @repo/example lint typecheck test` — all three pass
(9 test files, 25 tests). Cleaned up after verification so no example
package is committed.

Phase-1 limitations (documented in `docs/guides/scaffolding-a-feature.md`
and printed by the generator on success): no Payload CMS templates, no
React Query helpers, faker-driven factories left as stubs, single
entity / single use case, and aggregator wiring (core-api/root,
apps/web-next bindAll) is left as a manual checklist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:09:22 +02:00
b4ec48f058 docs(agents): bring agent-facing docs in line with the R44 fix
Six docs lagged after the post-merge R44 fix added withCapture +
reported-flag.ts. They mentioned withSpan only and described the
capture story as if it were inline in use-case / controller bodies.
This commit aligns them with what shipped.

CLAUDE.md (Key Conventions):
- "Spans applied at DI bind time" → "Spans + capture composed at DI
  bind time" with the withSpan(withCapture(factory)) sandwich and the
  outermost-span ordering note.
- "Capture at throw sites only" expanded to mention the
  __sentryReported flag, the three flag-checking sites (withCapture,
  SentryLogger, RecordingLogger), and where the helper lives.

AGENTS.md (Instrumentation conventions):
- Use case + controller wrapping example shows the full sandwich.
- Capture-rules table now explicitly says "via withCapture" for use
  cases and controllers, and "flag set, withCapture bails" for the
  bubbled cases.

packages/core-shared/AGENTS.md:
- "with-span.ts" entry split into a paired with-span + with-capture
  block, including the actual sandwich code.
- New entry for reported-flag.ts explaining the helper and why
  RecordingLogger inlines the check (boundary rule).
- Barrel re-export list updated.

docs/architecture/vertical-feature-spec.md (§16):
- The bind-production line now describes the withSpan(withCapture(...))
  sandwich, the outermost-span rationale, and the bubbled-error bail.

docs/architecture/dependency-flow.md (TRACER/LOGGER subsection):
- bindAll diagram updated: real repo line annotates inline calls; use
  case + controller lines show withSpan(withCapture(...)).

docs/guides/tdd-workflow.md (Asserting spans and captures):
- Direct-injection example shows the binder sandwich.
- Capture-assertion example explains the flag-bail behaviour and
  links to the new tests/r44-no-double-capture.test.ts e2e example.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:54:23 +02:00
281c7ac941 docs(html): align trace-tree code background with existing code-bg palette
The .trace-tree blocks I added in §06 / §08 used var(--ink-2) (#5b4a3c —
medium brown), which clashed with the page's dedicated --code-bg
(#16110d, deep dark). Switched to --code-bg + --code-paper for text,
plus the same border + inset/drop shadow as pre.code, so the new blocks
read consistently with every other code block on the page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:48:15 +02:00
01707e801b docs(html): update §06 + §08 with verified layer-by-layer instrumentation usage
After the user pushed back on intent-vs-shipped state, I greped each layer
and updated both explainers to reflect actual code, not documented intent.

data-flow-explainer.html §06 — "Tracing & error capture":
- New "Where instrumentation actually lives" table — per-layer breakdown
  of inline span / inline capture / composed-via-wrapper, with a verifiable
  grep showing only repos have inline calls.
- New "The wrapper sandwich" code block showing the actual repo body
  shape next to the bind-time withSpan(withCapture(...)) composition.
- Capture-rules table refined to reflect the R44 fix that just landed:
  use cases capture business-rule errors and output-schema failures
  (not bubbled-from-repo); controllers capture safeParse failures
  (not bubbled-from-use-case); the __sentryReported flag is what makes
  this safe.
- Double-report-guard paragraph now mentions withCapture, SentryLogger,
  and RecordingLogger all check the flag (not just SentryLogger).

di-explainer.html §08 — "Instrumentation symbols":
- Wiring path updated from "withSpan(tracer, ...)" to
  "withSpan(withCapture(...))" to reflect the post-merge wiring.
- New "Two wrappers, applied as a sandwich" table comparing what each
  wrapper does and where it fires; closing note that repos can't use
  the wrapper because they own per-call attributes.

Also bundled: a 1-line aesthetic SVG noise tweak in di-explainer.html
(opacity='0.25', baseFrequency 0.85→0.95) that was sitting in the
working tree before this session — preserved across the Plan 10 merge
via stash/pop and now committed alongside the doc update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:43:42 +02:00
f0775d6ecc feat(instrumentation): close R44 gap — throw-site capture for use cases + controllers
Plan 10 documented R44 (capture at originating-throw layer) but only the
R43 repo leg was wired. captureException had zero call sites in any
controller or use-case body. This commit closes the gap.

Mechanism:
- Extract __sentryReported flag helpers into core-shared/instrumentation/
  reported-flag.ts. SentryLogger switches to importing them; RecordingLogger
  carries an inlined copy (tooling → core boundary disallows the import).
- Add withCapture(logger, tags, fn) higher-order wrapper paralleling
  withSpan. On throw: capture-with-tags, mark, re-throw. Bail if the flag
  was already set — covers the bubbled-from-repo case so each error
  surfaces in the logger exactly once with the inner-most layer's tags.
- Apply withSpan(withCapture(factory)) in every feature's bind-production
  and bind-dev-seed: auth (3 use cases × 3 controllers), blog (3×3),
  marketing-pages (2×2), navigation (1×1), media (3×3). Span is outermost
  so the errored span timing reflects the capture-and-rethrow.
- RecordingLogger.captureException now also honours the flag — test
  capture counts stay honest when both repo and outer layer wrap.

Tests:
- packages/core-shared/src/instrumentation/with-capture.test.ts —
  4 cases covering success, capture-on-throw, mark-on-capture, no-double
  via the flag.
- packages/blog/tests/r44-no-double-capture.test.ts — 3 cases: repo throw
  → 1 capture with repo tags; controller parse fail → 1 capture with
  controller tags; success → 0 captures.

Verification: pnpm test 26/26, pnpm lint 15/15, pnpm typecheck 14/14.

Docs: ADR-014 and the refactor log gain a "Post-merge follow-up" section
recording the gap, the fix, and the underlying lesson (don't describe
intent as shipped state — grep first).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:28:22 +02:00
1771be3034 Merge branch 'worktree-feature+instrumentation-sentry'
Some checks failed
CI / typecheck + lint + boundaries + test + build (push) Has been cancelled
CI / Playwright e2e (push) Has been cancelled
Sentry PII guard (R31) / pii-guard (push) Has been cancelled
CI / Storybook smoke tests (push) Has been cancelled
2026-05-07 20:45:03 +02:00
60967a630d docs(plan-10): finalize ADR-014 + tick refactor log
Replaces the ADR-014 stub with the full Accepted-status decision record:
context, the 7 numbered decisions (vendor-neutral interfaces, full-depth
instrumentation, throw-site capture, PII rules, three Sentry projects,
ESLint boundary, Recording* test pair), alternatives considered,
positive/negative consequences, and an "execution notes" section
covering the spec deviations and surprises encountered.

Updates the refactor log: ticks all 33 tasks, populates "Decisions
deviated from spec" (PII key list extended with ipaddress; spec
section appended as §16 not §10; vite.config skipped; HTML section
numbering kept conservative) and "Notable surprises" (apps needed
direct core-shared deps; deep subpath exports for dynamic import;
peerDependenciesMeta.optional for @sentry/node and @sentry/react;
pre-existing lint debt; allowlist patterns needed **/-prefix for
flat-config glob matching from sub-package cwd).

Final verification (run before commit):
- pnpm test  → 26/26 tasks pass
- pnpm lint  → 15/15 tasks pass (warnings-only)
- pnpm typecheck → 14/14 tasks pass
- R31 grep gate (sendDefaultPii: true) → clean, no matches

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:41:54 +02:00
0a248d5be0 docs(html): data-flow-explainer §06 tracing + di-explainer §08 instrumentation symbols
Inserts a new §06 "Tracing & error capture" between the existing
"Tradeoffs by part" (§05) and the verdict (which moves to §07).
Includes the trace tree (HTTP → tRPC → controller → use-case → repo
→ Payload), capture-rules table (where captureException fires per
layer + the no-capture rule for defineErrorMiddleware), the
__sentryReported double-report guard explanation, and the R31–R38
PII rule list. Adds matching CSS (.trace-tree / .capture-rules /
.pii-rules) tuned to the existing dark-paper palette and Fraunces
heading font. Updates the contents nav from 6 → 7 columns.

di-explainer.html gets a new §08 "Instrumentation symbols" with cards
for TRACER and LOGGER, the bindAll() Rule-0 wiring path, and a note
on why feature containers also bind the symbols. Two-column grid
collapses to one on narrow viewports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:37:46 +02:00
85513ccbf9 docs: instrumentation testing patterns + dependency-flow + core-shared AGENTS update
Adds "Asserting spans and captures" section to tdd-workflow.md with
RecordingTracer/Logger usage and inline withSpan wrapping pattern for
direct-injection tests. Adds R49/R50 section to testing-strategy.md
covering the no-sentry guard, contract suite span assertions, and
RecordingTracer/Logger field reference. Adds "TRACER / LOGGER (Plan 10)"
subsection to dependency-flow.md showing the bindAll → feature-container
wiring path. Adds an "src/instrumentation/" section to core-shared/AGENTS.md
documenting the two interfaces, three impl pairs, withSpan helper, scrubbers,
both Next.js + Vite/React init helpers, and the subpath exports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:35:28 +02:00
c640cdf6c8 docs: instrumentation conventions in CLAUDE.md / AGENTS.md / vertical-feature-spec.md
Adds the seven Plan 10 conventions to CLAUDE.md (interfaces in core-shared,
spans at bind time, throw-site capture, PII rules, three Sentry projects,
orthogonal binding). Adds an "Instrumentation conventions" section to
AGENTS.md with repo constructor/method patterns, capture-rules table,
boundary allowlist, and test rules. Appends §16 "Instrumentation & error
capture" to vertical-feature-spec.md (the spec already has 15 sections,
so appending rather than slotting in as §10 to avoid renumbering).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:33:52 +02:00
d4b23cf35d chore(turbo): declare instrumentation env vars in globalEnv
Adds WEB_NEXT_SENTRY_DSN, NEXT_PUBLIC_WEB_NEXT_SENTRY_DSN, CMS_SENTRY_DSN,
WEB_TANSTACK_SENTRY_DSN, VITE_WEB_TANSTACK_SENTRY_DSN, VITE_GIT_COMMIT_SHA,
SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT_{WEB_NEXT,CMS,WEB_TANSTACK},
SENTRY_TRACES_SAMPLE_RATE, SENTRY_ENVIRONMENT, VERCEL_GIT_COMMIT_SHA,
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA, and VERCEL_ENV.

Clears turbo/no-undeclared-env-vars warnings on init-server.ts /
init-client.ts / bind-production.ts / next.config.mjs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:31:52 +02:00
955a763c66 feat(eslint+ci): R40 boundary rule for @sentry/* + R31 sendDefaultPii grep gate
Adds two flat-config blocks to core-eslint/base.js: (1) repo-wide
no-restricted-imports for @sentry/* with the R40 message, (2) an
allowlist override for the only paths permitted to import the Sentry
SDK directly — core-shared/instrumentation/sentry/**, the bind-sentry
DI files, the no-sentry test guards, and apps' instrumentation* /
next.config / vite.config / sentry.*.config files. Patterns use
**/-prefix so they match whether ESLint runs from the repo root or
from inside a sub-package.

Also adds the standard `argsIgnorePattern: "^_"` config (used
throughout the repo) and a Node-globals override for *.mjs/*.cjs/*.js
and *.config.{ts,tsx} so withSentryConfig in next.config.mjs lints
clean. Required adding `globals` as a core-eslint dep.

Adds .github/workflows/sentry-pii-guard.yml — a lightweight CI step
that fails any PR introducing `sendDefaultPii: true` (R31). Excludes
node_modules / dist / .next / .turbo from the grep so vendored SDK
JSDoc examples don't false-positive.

Pre-existing lint nits cleared as part of getting `pnpm lint` green:
- core-testing define-contract-suite.test.ts: void the unused
  receivedTracer (mirrors the next test's pattern)
- marketing-pages bind-dev-seed.ts: drop unused MockSiteSettingsRepository
  import
- marketing-pages get-site-settings.use-case.ts: drop the now-redundant
  eslint-disable for `_input`

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:31:15 +02:00
e1b6ecf578 feat(web-tanstack): Sentry instrumentation via @sentry/node + @sentry/react + R38 PII test
Adds initSentryServerNode + initSentryClientReact to core-shared
(Vite/non-Next variants of the existing init helpers — same R31/R32/R33
posture, R34/R35/R37 replay defaults). Extends no-sentry.ts to mock
@sentry/node + @sentry/react. Wires the web-tanstack server/client
instrumentation entry hooks and adds the R38 PII test.

Spec deviation: web-tanstack has no vite.config.ts yet (placeholder app
per its package.json). The @sentry/vite-plugin dep is added but unused
until the TanStack Start build is wired in a later plan. A minimal
src/vite-env.d.ts shims ImportMetaEnv for the client entry until the
full Vite types land.

@sentry/node and @sentry/react are added to core-shared as optional
peerDependencies so feature packages don't transitively pull them in;
they're also devDependencies of core-shared for typecheck/test runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:25:14 +02:00
d348cb9179 feat(cms): Sentry server instrumentation + withSentryConfig + R38 PII test
Adds apps/cms/instrumentation.ts (server-only — Payload admin client DSN
is out-of-scope per spec §8). Wraps the Payload-wrapped next config with
withSentryConfig. Adds the R38 PII scrubber test. Required adding
@repo/core-shared as a direct dep of cms (was only transitive before).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:14:56 +02:00
f911892d0b feat(web-next): Sentry instrumentation hooks + withSentryConfig + R38 PII test
Adds apps/web-next/instrumentation.ts (server) and instrumentation-client.ts
(browser) hooks, wraps next.config.mjs with withSentryConfig (R52), and adds
the R38 per-app PII scrubber smoke test.

Spec deviation: extend PII_KEY_SUBSTRINGS with "ipaddress" so keys like
ipAddress trigger key-level redaction (tighter posture than the spec's
substring list; existing scrub.test.ts still passes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:13:39 +02:00
d4bc045a28 test(features): R50 — repo contract suites assert span shape per method
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:09:50 +02:00
a4efceb104 feat(core-testing): R50 — contract context gains optional getTracer accessor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:08:39 +02:00
a943f95929 feat(media): wire instrumentation — media repo spans + getMedia/listMedia/deleteMedia withSpan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:01:46 +02:00
e14a23dccd feat(navigation): wire instrumentation — header repo spans + getHeader withSpan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 17:59:14 +02:00
404cb07e79 feat(marketing-pages): wire instrumentation — site-settings + pages spans + use-case/controller withSpan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 00:26:45 +02:00
64ffb009e1 feat(auth): wire instrumentation — users repo spans + sign-in/up/out withSpan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 00:24:20 +02:00
5903cef70a feat(blog): wire instrumentation — repo spans + use-case/controller withSpan + logger capture
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:18:13 +02:00