refactor(apps)!: delete web-tanstack demo app

Veect retrofit (ADR-027): the product is a hosted SaaS built on
web-next; apps/web-tanstack existed only as template demo surface for
the TanStack Start framework path. This slice removes the app and all
wiring that referenced it:

- turbo.json globalEnv: WEB_TANSTACK_SENTRY_DSN,
  VITE_WEB_TANSTACK_SENTRY_DSN, VITE_GIT_COMMIT_SHA,
  SENTRY_PROJECT_WEB_TANSTACK
- .env.example: the same four DSN/release vars
- generator e2e fixtures that stripped deps from the app's package.json
- coverage diff comment + test fixtures referencing apps/web-tanstack
- app-list entries in README, CLAUDE.md (port table, Sentry projects),
  AGENTS.md (tags, binder list, per-app docs), docs/glossary.md (App)
- pnpm-lock.yaml importer + orphaned transitive deps

Framework-support code in core packages stays: core-trpc's TanStack
provider, core-shared security/tanstack middleware, and the Sentry
react/node init adapters are generic TanStack support, not app wiring.
Prose in guides/ADRs/library traces is story 08 scope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 15:27:37 +02:00
parent 0db1c64d99
commit 986f8b2c26
28 changed files with 33 additions and 5727 deletions

View File

@@ -27,15 +27,12 @@ CMS_URL=http://localhost:3001
# WEB_NEXT_SENTRY_DSN=
# NEXT_PUBLIC_WEB_NEXT_SENTRY_DSN=
# CMS_SENTRY_DSN=
# WEB_TANSTACK_SENTRY_DSN=
# VITE_WEB_TANSTACK_SENTRY_DSN=
# Source-map upload at build time (production only).
# SENTRY_AUTH_TOKEN=
# SENTRY_ORG=
# SENTRY_PROJECT_WEB_NEXT=
# SENTRY_PROJECT_CMS=
# SENTRY_PROJECT_WEB_TANSTACK=
# OTel trace sample rate (0.0 = none, 1.0 = all). 0.1 recommended in dev.
# SENTRY_TRACES_SAMPLE_RATE=0.1
@@ -45,7 +42,6 @@ CMS_URL=http://localhost:3001
# VERCEL_GIT_COMMIT_SHA=
# NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA=
# VITE_GIT_COMMIT_SHA=
# --- Optional: core-audit (only when `gen core-package audit` is scaffolded) ---

View File

@@ -51,7 +51,7 @@ See `docs/guides/runbook.md` for the full workflow.
### Five tags
- **app** (4 packages) `apps/web-next`, `apps/web-tanstack`, `apps/cms`, `apps/storybook`
- **app** (3 packages) `apps/web-next`, `apps/cms`, `apps/storybook`
- **core-composition** (3 packages) `packages/core-api`, `core-cms`, `core-trpc`
- **core** (12 packages) `packages/core-shared`; `core-ui` is optional (scaffold with `pnpm turbo gen core-package ui`)
- **feature** (5 packages) `packages/auth`, `blog`, `media`, `marketing-pages`, `navigation`
@@ -359,7 +359,7 @@ Class names carry no `Payload` prefix — `ArticlesRepository`, `PagesRepository
### Apps call `bindAll()` per feature at boot
Each app (`web-next`, `web-tanstack`, `cms`) imports both binders per feature and uses a small dispatcher (`bindAll()`) that picks based on environment:
Each app (`web-next`, `cms`) imports both binders per feature and uses a small dispatcher (`bindAll()`) that picks based on environment:
- `USE_DEV_SEED === "true"` dev seed (explicit override; works in any `NODE_ENV`)
- `NODE_ENV === "production"` production (real Payload)
@@ -581,4 +581,4 @@ Per-package documentation lives in each `AGENTS.md`:
- `packages/core-ui/AGENTS.md` (optional generated by `pnpm turbo gen core-package ui`; see `turbo/generators/templates/core-package/ui/AGENTS.md.hbs`)
- `packages/auth/AGENTS.md`, `blog/AGENTS.md`, `media/AGENTS.md`, `marketing-pages/AGENTS.md`, `navigation/AGENTS.md`
- `packages/core-eslint/AGENTS.md`, `core-typescript/AGENTS.md`, `core-testing/AGENTS.md`
- `apps/cms/AGENTS.md`, `web-next/AGENTS.md`, `web-tanstack/AGENTS.md`, `storybook/AGENTS.md`
- `apps/cms/AGENTS.md`, `web-next/AGENTS.md`, `storybook/AGENTS.md`

View File

@@ -117,7 +117,7 @@ See `docs/guides/coverage.md` for the cookbook and ADR-020 for the full rational
- **Spans + capture composed at DI bind time** Use cases + controllers are wrapped at DI bind time in this order (outermost innermost): `withSpan → withCapture → withAudit → withAnalytics → withConsent → factory(deps)`. Apply `withAudit` when the manifest declares `audits`, `withAnalytics` when it declares `analyticsEvents`, `withConsent` when it declares `requiresConsent`. `withSpan` is always outermost so an errored span's timing reflects the capture-and-rethrow. Repository methods are different they call `this.tracer.startSpan(...)` and `this.logger.captureException(...)` inline per method because they own per-call attributes
- **Capture at throw sites only, with double-report guard** Repos capture infra errors inline; use cases + controllers capture via `withCapture` at bind time; `defineErrorMiddleware` never captures. Each error gets a non-enumerable `__sentryReported` flag the first time it's captured; `withCapture`, `OtelLogger`, and `RecordingLogger` all bail if the flag is set, so a bubbled error surfaces exactly once with the inner-most layer's tags (helper at `core-shared/instrumentation/reported-flag.ts`)
- **PII handling is non-negotiable** `sendDefaultPii: false` everywhere (CI grep gate); replay default-masks all text/inputs/media (allowlist starts empty); `setUser({ id })` only no email/username; server-side PII scrubbing happens at the OTel processor layer (`PiiScrubSpanProcessor` + `PiiScrubLogRecordProcessor`) before any exporter sees the data (ADR-017 §7)
- **Three apps, three Sentry projects** `WEB_NEXT_SENTRY_DSN`, `CMS_SENTRY_DSN`, `WEB_TANSTACK_SENTRY_DSN`. Browser DSNs use `NEXT_PUBLIC_` (web-next) and `VITE_` (web-tanstack) prefixes
- **Two apps, two Sentry projects** `WEB_NEXT_SENTRY_DSN`, `CMS_SENTRY_DSN`. The browser DSN uses the `NEXT_PUBLIC_` prefix (web-next)
- **Instrumentation binding is orthogonal to repo binding** `bindAll()`'s Rule 0 (DSN OTel+Sentry vs Noop) is independent of `USE_DEV_SEED` / `NODE_ENV`. Run `pnpm dev` with `WEB_NEXT_SENTRY_DSN` set to test the integration locally
- **Cross-feature events go through `IEventBus` (E0)** In-feature reactions are direct use-case calls, not bus publishes. The bus is for _crossing_ feature boundaries (e.g. `auth` `marketing-pages` welcome email)
- **Event contracts are public; handlers are private (E1)** Publisher's `events/<x>.event.ts` is exported from the feature root barrel. Consumer's `events/handlers/on-<publisher>-<event>.handler.ts` is never re-exported (ESLint-enforced via `core-eslint/rules/no-handler-reexport`)
@@ -146,10 +146,9 @@ Storybook MCP available at `http://localhost:6006/mcp` — use `list-all-documen
## Key Ports
| Service | Port |
| -------------- | ---- |
| Next.js | 3000 |
| Payload CMS | 3001 |
| TanStack Start | 3002 |
| PostgreSQL | 5432 |
| Storybook | 6006 |
| Service | Port |
| ----------- | ---- |
| Next.js | 3000 |
| Payload CMS | 3001 |
| PostgreSQL | 5432 |
| Storybook | 6006 |

View File

@@ -12,7 +12,7 @@ Read [`docs/guides/runbook.md`](./docs/guides/runbook.md) — day-1 onboarding (
```bash
pnpm install # Install + auto-wire husky pre-commit hooks
pnpm dev # All dev servers (web-next:3000, cms:3001, web-tanstack:3002, storybook:6006)
pnpm dev # All dev servers (web-next:3000, cms:3001, storybook:6006)
pnpm test # All tests
pnpm typecheck # TypeScript across all packages
pnpm lint # ESLint (incl. 8 conformance/* rules)

View File

@@ -1,114 +0,0 @@
# AGENTS.md — apps/web-tanstack
TanStack Start reference application using TanStack Router with file-based routing. Demonstrates that feature packages are framework-agnostic by consuming the same features as Next.js (via `@repo/core-api`) using TanStack's architecture instead.
## Purpose
Proof that features are framework-portable. This app consumes the exact same feature packages as `apps/web-next`, but through TanStack Start's server/client architecture instead of Next.js App Router. Once `@repo/core-trpc` is scaffolded, it can use the same tRPC routers via `TanstackTrpcProvider`.
## Port: 3002
```bash
pnpm dev --filter @repo/web-tanstack # http://localhost:3002
```
When `@repo/core-trpc` is installed, this app requires a tRPC endpoint (from `apps/web-next`):
```bash
pnpm dev --filter @repo/web-next # Serves tRPC at http://localhost:3000/api/trpc
pnpm dev --filter @repo/web-tanstack # http://localhost:3002
```
## Key Files
| File | Purpose |
|---|---|
| `src/routes/__root.tsx` | Root layout — wraps all routes with `<Outlet />` (add `<TanstackTrpcProvider>` after scaffolding `@repo/core-trpc`) |
| `src/routes/index.tsx` | Home page (`/`) |
| `src/routes/blog/index.tsx` | Blog listing (`/blog`) |
| `src/routes/blog/$slug.tsx` | Dynamic blog post (`/blog/:slug`) |
| `e2e/` | Playwright end-to-end tests |
## File-Based Routing
TanStack Router uses file-based routing where file paths map directly to URL routes:
| File | URL |
|---|---|
| `src/routes/__root.tsx` | Root (all routes) |
| `src/routes/index.tsx` | `/` |
| `src/routes/blog/index.tsx` | `/blog` |
| `src/routes/blog/$slug.tsx` | `/blog/:slug` |
Naming conventions:
- `__root.tsx` — special root layout
- `index.tsx` — index route for its directory
- `$paramName.tsx` — dynamic segment
## tRPC Setup (optional)
`@repo/core-trpc` is not installed by default. After scaffolding with `pnpm turbo gen core-package trpc`:
1. Update `src/routes/__root.tsx`:
```typescript
import { Outlet, createRootRoute } from "@tanstack/react-router";
import { TanstackTrpcProvider } from "@repo/core-trpc/tanstack";
export const Route = createRootRoute({
component: () => (
<TanstackTrpcProvider trpcUrl="http://localhost:3000/api/trpc">
<Outlet />
</TanstackTrpcProvider>
),
});
```
Note: `trpcUrl` must point to a running tRPC endpoint (e.g., from `apps/web-next`).
2. Fetch data in routes:
```typescript
import { createFileRoute } from "@tanstack/react-router";
import { useTRPC } from "@repo/core-trpc";
import { useQuery } from "@tanstack/react-query";
export const Route = createFileRoute("/blog/$slug")({
component: BlogPostPage,
});
function BlogPostPage() {
const { slug } = Route.useParams();
const trpc = useTRPC();
const { data, isLoading } = useQuery(trpc.blog.getBySlug.queryOptions({ slug }));
if (isLoading) return <p>Loading...</p>;
return <article>{data?.title}</article>;
}
```
## Dependencies
| Dependency | Purpose |
|---|---|
| `@repo/core-api` | AppRouter type |
| `@repo/core-trpc/tanstack` | TanStack tRPC client + provider (optional — scaffold first) |
| `@repo/core-ui` | Design system components (optional — scaffold first) |
| `@tanstack/react-router` | File-based routing |
| `@tanstack/react-query` | Data fetching + caching |
| `react` / `react-dom` | React 19 runtime |
## Test conventions
- e2e tests in `e2e/` folder: `*.spec.ts`
- Playwright config in `e2e/playwright.config.ts`
- Run: `pnpm test:e2e` (both Next.js and TanStack)
Parallel to `apps/web-next` e2e: validates that features work across frameworks.
## Cross-References
- **Feature packages:** `packages/{auth,blog,media,marketing-pages,navigation}/`
- **tRPC composition:** `packages/core-api/AGENTS.md`
- **tRPC client + provider (optional):** scaffold `@repo/core-trpc` first, then see `turbo/generators/templates/core-package/trpc/AGENTS.md.hbs`
- **UI components (optional):** scaffold with `pnpm turbo gen core-package ui`, then see `turbo/generators/templates/core-package/ui/AGENTS.md.hbs`
- **Next.js app (serves tRPC):** `apps/web-next/AGENTS.md`

View File

@@ -1,37 +0,0 @@
// apps/web-tanstack/app.config.ts
// TanStack Start / Nitro server configuration.
// Registers the core-shared security headers middleware so every response
// emits the six security headers and a per-request CSP nonce.
//
// Wire-up pattern (Nitro/H3 server hook):
// withSecurityHeaders() generates nonce + builds six headers.
// setHeader calls forward them to the response.
// req.headers["x-nonce"] is set so downstream loaders can call
// getNonce(event.node.req) from @repo/core-shared/security/tanstack.
import { defineConfig } from "@tanstack/start/config";
import { withSecurityHeaders } from "@repo/core-shared/security/tanstack";
interface H3SecurityEvent {
node: {
req: { headers: Record<string, string | string[] | undefined> };
res: { setHeader: (name: string, value: string) => void };
};
}
/**
* Nitro/H3 server hook: emits six security headers on every response and
* forwards the per-request nonce in req.headers["x-nonce"] for downstream
* access via getNonce() from @repo/core-shared/security/tanstack.
*/
export function applySecurityHeaders(event: H3SecurityEvent): void {
const { nonce, headers } = withSecurityHeaders();
for (const [k, v] of Object.entries(headers)) {
event.node.res.setHeader(k, v);
}
event.node.req.headers["x-nonce"] = nonce;
}
export default defineConfig({
server: { hooks: { request: applySecurityHeaders } },
});

View File

@@ -1,12 +0,0 @@
import { test, expect } from "@playwright/test";
test.skip(
"TanStack home renders site name + nav (pending TanStack Start runtime)",
async ({ page }) => {
// Pending: web-tanstack has no dev server yet. When the TanStack Start
// runtime is wired (future plan), update the playwright.config.ts
// webServer to start it on port 3002 and remove this skip.
await page.goto("http://localhost:3002");
await expect(page.locator("h1").first()).toBeVisible();
},
);

View File

@@ -1,3 +0,0 @@
import baseConfig from "@repo/core-eslint/base";
export default baseConfig;

View File

@@ -1,45 +0,0 @@
{
"name": "@repo/web-tanstack",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"build": "echo 'placeholder — TanStack Start build configured in later plan'",
"dev": "echo 'placeholder'",
"lint": "eslint .",
"test": "vitest run --passWithNoTests",
"test:e2e": "playwright test",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@repo/blog": "workspace:*",
"@repo/core-api": "workspace:*",
"@repo/core-shared": "workspace:*",
"@repo/marketing-pages": "workspace:*",
"@repo/navigation": "workspace:*",
"@sentry/node": "^10.52.0",
"@sentry/react": "^10.52.0",
"@tanstack/react-query": "^5.66.0",
"@tanstack/react-router": "^1.120.0",
"@tanstack/start": "^1.120.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"vinxi": "0.5.3"
},
"devDependencies": {
"@playwright/test": "^1.50.0",
"@repo/core-eslint": "workspace:*",
"@repo/core-testing": "workspace:*",
"@repo/core-typescript": "workspace:*",
"@sentry/vite-plugin": "^5.2.1",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.0",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitest/coverage-v8": "^3.2.4",
"jsdom": "^25.0.0",
"vitest": "^3.0.0"
}
}

View File

@@ -1,21 +0,0 @@
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./e2e",
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
reporter: "list",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
// No webServer: web-tanstack tests run against the shared web-next backend
// (port 3000). When TanStack Start runtime is wired in a future plan, add
// a webServer block here pointing at port 3002.
});

View File

@@ -1,50 +0,0 @@
// apps/web-tanstack/src/instrumentation-client.test.ts
import { describe, it, expect, vi, beforeEach } from "vitest";
// Hoist the mock so it's active when instrumentation-client runs its
// top-level initSentryClientReact call on import.
const initSentryClientReactMock = vi.hoisted(() => vi.fn());
vi.mock("@repo/core-shared/instrumentation/sentry/init-client-react", () => ({
initSentryClientReact: initSentryClientReactMock,
}));
describe("instrumentation-client", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.resetModules();
});
it("passes nonce from csp-nonce meta tag to initSentryClientReact", async () => {
const meta = document.createElement("meta");
meta.setAttribute("name", "csp-nonce");
meta.setAttribute("content", "test-nonce-xyz");
document.head.appendChild(meta);
try {
await import("./instrumentation-client");
} finally {
document.head.removeChild(meta);
}
expect(initSentryClientReactMock).toHaveBeenCalledWith(
expect.objectContaining({ nonce: "test-nonce-xyz" }),
);
});
it("passes empty string nonce when no csp-nonce meta tag is present", async () => {
await import("./instrumentation-client");
expect(initSentryClientReactMock).toHaveBeenCalledWith(
expect.objectContaining({ nonce: "" }),
);
});
it("passes web-tanstack as the app tag", async () => {
await import("./instrumentation-client");
expect(initSentryClientReactMock).toHaveBeenCalledWith(
expect.objectContaining({ app: "web-tanstack" }),
);
});
});

View File

@@ -1,18 +0,0 @@
// apps/web-tanstack/src/instrumentation-client.ts
// Browser-entry hook. Imported at the top of the client entry file.
import { initSentryClientReact } from "@repo/core-shared/instrumentation/sentry/init-client-react";
function getNonce(): string {
if (typeof document === "undefined") return "";
return (
document.querySelector('meta[name="csp-nonce"]')?.getAttribute("content") ??
""
);
}
initSentryClientReact({
dsn: import.meta.env["VITE_WEB_TANSTACK_SENTRY_DSN"],
app: "web-tanstack",
release: import.meta.env["VITE_GIT_COMMIT_SHA"],
nonce: getNonce(),
});

View File

@@ -1,12 +0,0 @@
// apps/web-tanstack/src/instrumentation.ts
// Server-entry hook. Imported at the top of the server entry file before any
// request handler runs. Initializes the OTel SDK here so PII scrub processors
// are active from the very first request (C1 fix — closes the startup window
// where Sentry auto-instrumentation could send unscrubbed errors).
import { initOtelServerNode } from "@repo/core-shared/instrumentation/otel/init-server-node";
initOtelServerNode({
dsn: process.env["WEB_TANSTACK_SENTRY_DSN"] ?? "",
serviceName: "web-tanstack",
environment: process.env["NODE_ENV"] ?? "development",
});

View File

@@ -1,29 +0,0 @@
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
// Mock @tanstack/react-router so we don't need a full router context.
// useLoaderData is supplied so the component can read the nonce from loader data.
vi.mock("@tanstack/react-router", () => ({
createRootRoute: vi.fn((opts: { component: React.ComponentType }) => ({
options: { component: opts.component },
useLoaderData: () => ({ nonce: "test-nonce-abc" }),
})),
Outlet: () => <div data-testid="outlet" />,
}));
describe("Root route", () => {
it("renders csp-nonce meta tag and Outlet", async () => {
const { Route } = await import("./__root");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const RootComponent = (Route as any).options
.component as React.ComponentType;
render(<RootComponent />);
expect(screen.getByTestId("outlet")).toBeInTheDocument();
const metaTag = document.querySelector('meta[name="csp-nonce"]');
expect(metaTag).toBeInTheDocument();
expect(metaTag?.getAttribute("content")).toBe("test-nonce-abc");
});
});

View File

@@ -1,25 +0,0 @@
import { Outlet, createRootRoute } from "@tanstack/react-router";
import { getNonce } from "@repo/core-shared/security/tanstack";
export const Route = createRootRoute({
loader: async () => {
try {
// Server-side during SSR: read nonce set by applySecurityHeaders middleware.
// Fails gracefully on client-side navigation (nonce already in DOM from SSR).
const { getEvent } = await import("vinxi/http");
return { nonce: getNonce(getEvent().node.req) };
} catch {
return { nonce: "" };
}
},
component: () => {
const { nonce } = Route.useLoaderData();
return (
<>
{/* nonce exposed to client so instrumentation-client.ts can read it */}
<meta name="csp-nonce" content={nonce} />
<Outlet />
</>
);
},
});

View File

@@ -1,14 +0,0 @@
import { createFileRoute } from "@tanstack/react-router";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const Route = createFileRoute("/" as any)({
component: Home,
});
function Home() {
return (
<main>
<p>This page is rendered by TanStack Router and consumes the same feature packages as the Next.js app.</p>
</main>
);
}

View File

@@ -1,11 +0,0 @@
// Minimal Vite-style env typing for the instrumentation-client entry.
// When the full TanStack Start / Vite build is wired in a later plan,
// replace this with `/// <reference types="vite/client" />`.
interface ImportMetaEnv {
readonly VITE_WEB_TANSTACK_SENTRY_DSN?: string;
readonly VITE_GIT_COMMIT_SHA?: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@@ -1,4 +0,0 @@
{
"status": "passed",
"failedTests": []
}

View File

@@ -1,13 +0,0 @@
{
"extends": "@repo/core-typescript/base.json",
"compilerOptions": {
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"jsx": "react-jsx",
"paths": {
"@/*": ["./src/*"]
},
"types": ["vitest/globals", "@testing-library/jest-dom"]
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
}

View File

@@ -1,4 +0,0 @@
{
"extends": ["//"],
"tags": ["app"]
}

View File

@@ -1,26 +0,0 @@
import path from "node:path";
import { mergeConfig } from "vitest/config";
import { jsdomVitestConfig } from "@repo/core-typescript/vitest.base.jsdom";
// Coverage excludes mirror the feature-package pattern (see
// packages/auth/vitest.config.ts): framework glue is excluded, thresholds
// stay inherited from the shared base — never lowered here.
export default mergeConfig(jsdomVitestConfig, {
esbuild: { jsx: "automatic" },
test: {
coverage: {
exclude: [
// TanStack Router route definitions — framework-invoked entry
// points, covered by Playwright e2e; not unit tests
"src/routes/**",
// Server-entry OTel/Sentry boot wiring — import-time side effects
// run once at startup (same class as feature DI bootstrap).
// instrumentation-client.ts stays counted (it has a unit test).
"src/instrumentation.ts",
// Ambient type declarations — no executable code
"src/**/*.d.ts",
],
},
},
resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
});

View File

@@ -39,7 +39,7 @@ A tag for packages that compose feature exports — `core-api`, `core-cms`, `cor
A package providing build/lint/test infrastructure — `core-eslint`, `core-typescript`, `core-testing`. May only depend on other tooling.
**App**:
A runtime entry point under `apps/``web-next`, `web-tanstack`, `cms`, `storybook`.
A runtime entry point under `apps/``web-next`, `cms`, `storybook`.
## Clean Architecture layers (per feature)

5276
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -71,7 +71,7 @@ const ALLOWED_GLOBS = [
// Tooling packages that don't generate a vitest lcov (no @vitest/coverage-v8)
/^packages\/core-testing\//,
/^packages\/core-eslint\//,
// App packages (web-next, web-tanstack, cms) do not configure
// App packages (web-next, cms) do not configure
// @vitest/coverage-v8, so their source files never appear in the merged lcov.
/^apps\//,
// core-shared Sentry client init files — explicitly excluded from per-package

View File

@@ -246,15 +246,12 @@ describe("computeDiffCoverage", () => {
test("skips apps/ files (app packages don't configure @vitest/coverage-v8)", () => {
const lcov = parseLcov(lcovText);
const diff = new Map([
// web-next and web-tanstack have no @vitest/coverage-v8 — never in lcov
// web-next and cms have no @vitest/coverage-v8 — never in lcov
["apps/web-next/instrumentation-client.ts", new Set([1, 2, 3, 4, 5, 6])],
["apps/web-next/middleware.ts", new Set([1, 2, 3, 4, 5])],
["apps/web-next/src/app/layout.tsx", new Set([1, 2, 3])],
[
"apps/web-tanstack/src/instrumentation-client.ts",
new Set([1, 2, 3, 4, 5]),
],
["apps/web-tanstack/app.config.ts", new Set([1, 2, 3])],
["apps/cms/src/instrumentation.ts", new Set([1, 2, 3, 4, 5])],
["apps/cms/src/payload.config.ts", new Set([1, 2, 3])],
]);
const result = computeDiffCoverage(diff, lcov);
assert.equal(result.status, "pass");

View File

@@ -10,14 +10,10 @@
"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",
"SENTRY_PROJECT_CMS",
"SENTRY_PROJECT_WEB_TANSTACK",
"SENTRY_TRACES_SAMPLE_RATE",
"SENTRY_ENVIRONMENT",
"VERCEL_GIT_COMMIT_SHA",

View File

@@ -67,7 +67,6 @@ describe("e2e: core-package trpc", () => {
// and navigation features depend on it for their ./ui tRPC hooks.
for (const pkgDir of [
["apps", "web-next"],
["apps", "web-tanstack"],
["packages", "blog"],
["packages", "marketing-pages"],
["packages", "navigation"],

View File

@@ -64,7 +64,6 @@ describe("e2e: core-package ui", () => {
// Strip @repo/core-ui from app package.json files so pnpm install
// succeeds without the package being present (simulating the post-removal state).
stripCoreUiDep(join(tmp, "apps", "web-next", "package.json"));
stripCoreUiDep(join(tmp, "apps", "web-tanstack", "package.json"));
stripCoreUiDep(join(tmp, "apps", "storybook", "package.json"));
execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, {