Commit Graph

45 Commits

Author SHA1 Message Date
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
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
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
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
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
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
fbcee9b9f2 feat(core-shared): bindNoopInstrumentation + bindSentryInstrumentation
Adds DI binder functions for instrumentation. bindNoopInstrumentation binds
NoopTracer + NoopLogger; bindSentryInstrumentation calls initSentryServer then
binds SentryTracer + SentryLogger. Both are idempotent (unbind-first). Adds
inversify + reflect-metadata as devDependencies so container tests compile.
Re-exports from instrumentation barrel. 6 new tests (3+3).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 00:01:54 +02:00
b08da12447 fix(core-shared): TypeScript type fixes for Sentry adapter layer — null attr filter, structural event types, non-null assertions, vi.stubEnv 2026-05-06 23:56:46 +02:00
5f74230ad4 feat(core-shared): initSentryClient helper (R34, R35, R37 mandatory replay defaults) 2026-05-06 23:48:08 +02:00
a9f559117e feat(core-shared): initSentryServer helper (R31, R32, R33, R37 defaults) 2026-05-06 23:47:18 +02:00
2631b757b0 feat(core-shared): PII scrubbers — beforeSend (R32) + beforeSendTransaction (R33) 2026-05-06 23:46:42 +02:00
6d4522438d feat(core-shared): SentryLogger with double-report guard + R36 user-context strip 2026-05-06 23:45:45 +02:00
a324da09c5 feat(core-shared): SentryTracer adapter 2026-05-06 23:45:05 +02:00
e133b92fe6 feat(core-shared): symbols + barrel for instrumentation subpath 2026-05-06 23:42:26 +02:00
0ffda8078f feat(core-shared): add withSpan higher-order helper 2026-05-06 23:41:54 +02:00
fdd4e9141b feat(core-shared): add ILogger interface + NoopLogger 2026-05-06 23:41:27 +02:00
f1051ded9b feat(core-shared): add NoopTracer 2026-05-06 23:41:01 +02:00
fcd10e8774 feat(core-shared): add ITracer/ISpan interfaces 2026-05-06 23:40:35 +02:00
ef2b8e300e docs(plan-9): doc-pass slice 1 — CLAUDE.md, core-shared AGENTS, architecture, plan-8 annotations
First slice of the combined Plan 8 + Plan 9 doc-update pass:
- CLAUDE.md Key Conventions: append schema-in-use-case, presenter,
  controller unknown input, feature-scoped tRPC error mapping, public
  surface split (./ui)
- packages/core-shared/AGENTS.md: document defineErrorMiddleware export
  + t re-export from trpc/init
- docs/superpowers/plans/2026-05-05-plan-8-*.md and matching spec:
  one-line note that some controller/router patterns shifted in Plan 9;
  link to the Plan 9 refactor log
- docs/architecture/overview.md: data-flow box now shows xProcedure +
  xInputSchema + xOutputSchema.parse + presenter + middleware lanes;
  three explanatory paragraphs added (schemas, presenter, error mapping)
- docs/architecture/dependency-flow.md: app-side ./ui subpath note,
  allowed/disallowed examples updated for Plan 9 paths

Remaining doc-pass items (root AGENTS.md, per-feature AGENTS.md ×5,
core-testing AGENTS.md, adding-a-feature.md, tdd-workflow.md,
testing-strategy.md, vertical-feature-spec.md) follow in subsequent
commits — to be dispatched in parallel.
2026-05-06 16:43:13 +02:00
aac37fd9af docs(core-shared): correct defineErrorMiddleware jsdoc to match implementation
Code-quality reviewer flagged a stale 'try/catch' phrase in the jsdoc
that didn't match the actual result.ok inspection pattern. Updated
description to accurately describe how tRPC v11 middleware sees errors
(returned result, not thrown exception) and how the middleware
discriminates and rethrows.

Pure docstring change — no behavioral or signature impact.
2026-05-06 11:54:51 +02:00
e25b1f7a1c feat(core-shared): add defineErrorMiddleware factory + export t
Factory takes [[ErrorCtor, TRPC_CODE], ...] tuples and returns a tRPC
middleware that translates matching domain errors to TRPCError. Discrim-
inates by instanceof; preserves original error as cause; unmapped
errors propagate (tRPC then wraps them as INTERNAL_SERVER_ERROR with
the original error as .cause — middleware does not interfere).

core-shared never enumerates feature errors — each feature passes its
own constructors in via integrations/api/procedures.ts (Tasks 3-7).

Also exports the `t` instance from trpc/init.ts so feature procedure
files can do t.procedure.use(...).

Also fixes tsconfig.json: rootDir set to "." and @/* path alias added
so test files using @/ resolve correctly under tsc --noEmit.

Refactor log: §1, §2, §4
Spec: R13–R17
2026-05-06 11:43:45 +02:00
bf6affd404 feat(core-typescript): split vitest base into node + jsdom flavors
Adds vitest.base.node and vitest.base.jsdom with safety defaults
(clearMocks, restoreMocks, mockReset, unstubGlobals, sequence.shuffle)
and coverage thresholds (80/75/80/80). Migrates all feature configs
to the new base. Existing baseVitestConfig kept as backwards-compat
re-export of nodeVitestConfig.

Spec: §6.2
2026-05-05 14:04:19 +02:00
0972645ebb refactor: rename eslint-config + typescript-config to core-eslint + core-typescript
Aligns tooling packages with the core-* naming convention used by all
other foundation packages (core-shared, core-cms, core-api, core-trpc,
core-ui). Updates ~50 files: package.json names, devDependencies,
tsconfig extends, eslint.config imports, vitest.config imports, AGENTS.md
references, and the boundaries plugin patterns to match the new paths.

The tooling-specific patterns in boundaries/elements are now ordered BEFORE
the broader core-* pattern to ensure correct first-match-wins behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 10:37:07 +02:00
956b38fb00 docs(agents): add per-package AGENTS.md for all core-* packages 2026-05-05 09:37:47 +02:00
22bee5362f feat(eslint-config): add boundaries plugin enforcing app→feature→core graph
- Install eslint-plugin-boundaries@^4.2.2 to enforce three-tag boundary model
- Configure element types: app, core-composition (core-api/core-cms), core, feature, tooling
- Enforce unidirectional dependency graph: apps→features→core, core-composition→features
- Add eslint.config.js to all 17 packages and apps (required for ESLint 9 flat config)
- Fix pre-existing linting issues to achieve clean lint pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:21:01 +02:00
614b0178a0 feat(core-shared): wire root index.ts barrel 2026-05-04 20:45:09 +02:00
884b0c01e8 fix(core-shared): narrow Payload Field union before accessing name in tests
Payload's Field type is a discriminated union; field.name only exists on
named variants. Tests now narrow on type (and 'name' in field for groups)
before reading variant-specific properties.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 20:43:23 +02:00
428346a36d feat(core-shared): add tRPC context factory 2026-05-04 20:40:52 +02:00
cd2f3b1fff feat(core-shared): add tRPC init with superjson 2026-05-04 20:40:42 +02:00
a9a8d32726 feat(core-shared): add payload barrel export 2026-05-04 20:39:54 +02:00
520a792b7f feat(core-shared): add toIsoString helper 2026-05-04 20:37:26 +02:00
3ffe752c7a feat(core-shared): add requireEnv helper 2026-05-04 20:37:12 +02:00
2b2de66b5d feat(core-shared): add slugifyIfMissing hook 2026-05-04 20:37:00 +02:00
124ccabc5f feat(core-shared): add setPublishedAt hook 2026-05-04 20:36:45 +02:00
6bd428214f feat(core-shared): add cta block 2026-05-04 20:36:30 +02:00
2d838b2dcf feat(core-shared): add seoFields group 2026-05-04 20:36:17 +02:00
f2f8e2b3b3 feat(core-shared): add slugField helper 2026-05-04 20:35:59 +02:00
5942317222 feat(core-shared): add isAdmin access helper 2026-05-04 20:35:36 +02:00
9a2158211b test(core-shared): wire shared vitest base 2026-05-04 20:34:08 +02:00
b4a9994dc2 feat(core-shared): scaffold empty package with exports + tags 2026-05-04 20:29:57 +02:00