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>
This commit is contained in:
2026-05-07 20:25:14 +02:00
parent d348cb9179
commit e1b6ecf578
13 changed files with 548 additions and 0 deletions

View File

@@ -27,3 +27,36 @@ vi.mock("@sentry/nextjs", () => ({
getActiveSpan: vi.fn(() => undefined),
getCurrentHub: vi.fn(() => ({ getClient: () => undefined })),
}));
vi.mock("@sentry/node", () => ({
init: vi.fn(),
startSpan: vi.fn((_opts: unknown, fn: (span: unknown) => unknown) =>
fn({ setAttribute: vi.fn(), setStatus: vi.fn() }),
),
captureException: vi.fn(),
captureMessage: vi.fn(),
addBreadcrumb: vi.fn(),
setUser: vi.fn(),
setContext: vi.fn(),
setTag: vi.fn(),
setExtra: vi.fn(),
withScope: vi.fn((fn: (scope: unknown) => unknown) =>
fn({ setTag: vi.fn(), setExtra: vi.fn() }),
),
getActiveSpan: vi.fn(() => undefined),
}));
vi.mock("@sentry/react", () => ({
init: vi.fn(),
captureException: vi.fn(),
captureMessage: vi.fn(),
addBreadcrumb: vi.fn(),
setUser: vi.fn(),
setContext: vi.fn(),
setTag: vi.fn(),
setExtra: vi.fn(),
withScope: vi.fn((fn: (scope: unknown) => unknown) =>
fn({ setTag: vi.fn(), setExtra: vi.fn() }),
),
replayIntegration: vi.fn(() => ({ name: "Replay" })),
}));