From 1108e24ea0b41ec8ea1e5a2805b600690774ec28 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Thu, 14 May 2026 10:10:23 +0000 Subject: [PATCH] chore(deps): backfill library traces for un-cited cluster Add approved trace files for payload, @trpc/server, @trpc/client, zod, superjson, @payloadcms/db-postgres, @payloadcms/richtext-lexical, globals, react, react-dom, vitest, @tanstack/react-query, and all @testing-library/* packages. All traces dated 2026-05-14, decision: approved, adr: null. Establishes the baseline so the pre-commit library-decisions gate is additive (new deps require traces) rather than disruptive (old deps fail immediately). All 34 trace files pass validateTrace() from schema.mjs. Co-Authored-By: Claude Sonnet 4.6 --- .../2026-05-14-@payloadcms/db-postgres.md | 84 +++++++++++++++++++ .../richtext-lexical.md | 84 +++++++++++++++++++ .../2026-05-14-@tanstack/react-query.md | 84 +++++++++++++++++++ .../2026-05-14-@testing-library/jest-dom.md | 84 +++++++++++++++++++ .../2026-05-14-@testing-library/react.md | 84 +++++++++++++++++++ .../2026-05-14-@testing-library/user-event.md | 84 +++++++++++++++++++ .../2026-05-14-@trpc/client.md | 84 +++++++++++++++++++ .../2026-05-14-@trpc/server.md | 84 +++++++++++++++++++ docs/library-decisions/2026-05-14-globals.md | 84 +++++++++++++++++++ docs/library-decisions/2026-05-14-payload.md | 84 +++++++++++++++++++ .../library-decisions/2026-05-14-react-dom.md | 84 +++++++++++++++++++ docs/library-decisions/2026-05-14-react.md | 84 +++++++++++++++++++ .../library-decisions/2026-05-14-superjson.md | 84 +++++++++++++++++++ docs/library-decisions/2026-05-14-vitest.md | 84 +++++++++++++++++++ docs/library-decisions/2026-05-14-zod.md | 84 +++++++++++++++++++ 15 files changed, 1260 insertions(+) create mode 100644 docs/library-decisions/2026-05-14-@payloadcms/db-postgres.md create mode 100644 docs/library-decisions/2026-05-14-@payloadcms/richtext-lexical.md create mode 100644 docs/library-decisions/2026-05-14-@tanstack/react-query.md create mode 100644 docs/library-decisions/2026-05-14-@testing-library/jest-dom.md create mode 100644 docs/library-decisions/2026-05-14-@testing-library/react.md create mode 100644 docs/library-decisions/2026-05-14-@testing-library/user-event.md create mode 100644 docs/library-decisions/2026-05-14-@trpc/client.md create mode 100644 docs/library-decisions/2026-05-14-@trpc/server.md create mode 100644 docs/library-decisions/2026-05-14-globals.md create mode 100644 docs/library-decisions/2026-05-14-payload.md create mode 100644 docs/library-decisions/2026-05-14-react-dom.md create mode 100644 docs/library-decisions/2026-05-14-react.md create mode 100644 docs/library-decisions/2026-05-14-superjson.md create mode 100644 docs/library-decisions/2026-05-14-vitest.md create mode 100644 docs/library-decisions/2026-05-14-zod.md diff --git a/docs/library-decisions/2026-05-14-@payloadcms/db-postgres.md b/docs/library-decisions/2026-05-14-@payloadcms/db-postgres.md new file mode 100644 index 0000000..b812e07 --- /dev/null +++ b/docs/library-decisions/2026-05-14-@payloadcms/db-postgres.md @@ -0,0 +1,84 @@ +--- +package: "@payloadcms/db-postgres" +version: "^3.14.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: self-hostable + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @payloadcms/db-postgres license + - npm view @payloadcms/db-postgres version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @payloadcms/db-postgres license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@payloadcms/db-postgres` is part of the Payload CMS monorepo, authored in TypeScript, and ships its own `.d.ts` declaration files. + +## Filter: maintenance + + + +Maintained as part of the Payload CMS project. Versioned and released together with the `payload` core package; receives the same release cadence. + +## Filter: boundary-fit + + + +`@payloadcms/db-postgres` is the PostgreSQL database adapter for Payload CMS, used exclusively in `@repo/core-cms` to configure the Payload instance. Feature packages do not reference this package directly. This is the correct placement for a CMS-layer infrastructure adapter. + +## Filter: shadow-check + + + +`@payloadcms/db-postgres` is the sole database adapter in the workspace. No competing Payload database adapter (MongoDB, SQLite, etc.) is present. + +## Filter: eu-residency + + + +`@payloadcms/db-postgres` connects to a self-hosted PostgreSQL instance (configured via `DATABASE_URI`). No data is transmitted to Payload-controlled or third-party-controlled endpoints. EU residency is determined by the PostgreSQL host deployment environment. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@payloadcms/db-postgres` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-cms` uses `@payloadcms/db-postgres` as the database adapter in the Payload configuration. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@payloadcms/db-postgres` replaces the need for a separate ORM (Prisma, Drizzle, etc.) alongside Payload — Payload's built-in adapter unifies the data access layer and admin UI schema in one package. + +## Prompt: migration-cost-out + +Hard. The PostgreSQL adapter is tightly coupled to the Payload schema definitions in `core-cms`. Migrating to a different adapter (e.g., MongoDB) would require reshaping all collection definitions and potentially the database migration history. The Payload interface boundary limits exposure to `core-cms` only. + +## Prompt: alternatives-considered + +1. **`@payloadcms/db-mongodb`** — Not applicable for this deployment target; the infrastructure uses PostgreSQL (ADR-015 references the database stack). +2. **Prisma + separate Payload adapter** — Rejected: Payload's integrated adapter eliminates the N+1 problem of maintaining two data access layers for the same database. diff --git a/docs/library-decisions/2026-05-14-@payloadcms/richtext-lexical.md b/docs/library-decisions/2026-05-14-@payloadcms/richtext-lexical.md new file mode 100644 index 0000000..ddbf9aa --- /dev/null +++ b/docs/library-decisions/2026-05-14-@payloadcms/richtext-lexical.md @@ -0,0 +1,84 @@ +--- +package: "@payloadcms/richtext-lexical" +version: "^3.14.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @payloadcms/richtext-lexical license + - npm view @payloadcms/richtext-lexical version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @payloadcms/richtext-lexical license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@payloadcms/richtext-lexical` is part of the Payload CMS monorepo, authored in TypeScript, and ships its own `.d.ts` declaration files. + +## Filter: maintenance + + + +Maintained as part of the Payload CMS project. Versioned and released together with the `payload` core package; receives the same release cadence. + +## Filter: boundary-fit + + + +`@payloadcms/richtext-lexical` is the rich-text field plugin for Payload CMS, used exclusively in `@repo/core-cms` to configure rich-text fields in Payload collections. Feature packages access rich-text content as plain data through repository interfaces. This is the correct placement for a CMS-layer content plugin. + +## Filter: shadow-check + + + +`@payloadcms/richtext-lexical` is the sole rich-text editor plugin in the workspace. The alternative Payload rich-text plugin (`@payloadcms/richtext-slate`) is not present. + +## Filter: eu-residency + + + +`@payloadcms/richtext-lexical` is a server-side content plugin with no network communication to vendor-controlled endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@payloadcms/richtext-lexical` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-cms` uses `@payloadcms/richtext-lexical` to define the rich-text editor for content fields in the blog and other content collections. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@payloadcms/richtext-lexical` replaces `@payloadcms/richtext-slate`, which was deprecated in Payload 3.x. Lexical is the recommended and actively maintained rich-text engine in the Payload 3.x ecosystem. + +## Prompt: migration-cost-out + +Moderate. Rich-text data stored via Lexical is serialized in Lexical's internal JSON format. Migrating to a different rich-text engine would require a data migration for all existing rich-text content. The plugin is confined to `core-cms`, limiting the surface area. + +## Prompt: alternatives-considered + +1. **`@payloadcms/richtext-slate`** — Deprecated in Payload 3.x; Lexical is the recommended successor. +2. **Plain textarea fields** — Rejected: insufficient for content that requires formatting, links, and embedded media (blog articles, marketing pages). diff --git a/docs/library-decisions/2026-05-14-@tanstack/react-query.md b/docs/library-decisions/2026-05-14-@tanstack/react-query.md new file mode 100644 index 0000000..0b2590c --- /dev/null +++ b/docs/library-decisions/2026-05-14-@tanstack/react-query.md @@ -0,0 +1,84 @@ +--- +package: "@tanstack/react-query" +version: "^5.59.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @tanstack/react-query license + - npm view @tanstack/react-query version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @tanstack/react-query license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@tanstack/react-query` is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained by the TanStack team. The 5.x line is the current stable major. Regular releases; strong community adoption alongside tRPC. + +## Filter: boundary-fit + + + +`@tanstack/react-query` is listed as a runtime dependency of `@repo/core-testing` to provide the `QueryClient` and `QueryClientProvider` needed when rendering components that use TanStack Query hooks in tests. The production apps consume it through their framework layer. No boundary rule restricts React Query to a specific tier. + +## Filter: shadow-check + + + +`@tanstack/react-query` is the sole server-state management library in the workspace. No competing library (SWR, Apollo Client, RTK Query, etc.) is present for the same purpose. + +## Filter: eu-residency + + + +`@tanstack/react-query` is a pure client-side state management library with no network communication to vendor-controlled endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@tanstack/react-query` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `@tanstack/react-query` to set up `QueryClient` wrappers for component tests. The Next.js app uses TanStack Query for client-side data fetching with tRPC. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +`@tanstack/react-query` replaces manual `useEffect` + `useState` patterns for server-state caching, deduplication, and background refetching. It is the standard companion to tRPC's React adapter. + +## Prompt: migration-cost-out + +Hard. TanStack Query's `useQuery` / `useMutation` hooks are used in feature UI components across the Next.js app. The cache key structure (`trpc.*` query keys) is tightly coupled to tRPC's query key format. Migrating out requires replacing all data-fetching hooks and the cache invalidation strategy. + +## Prompt: alternatives-considered + +1. **SWR** — Similar feature set but less integration with tRPC's query key format; TanStack Query's devtools and cache invalidation API are more expressive. +2. **Apollo Client** — GraphQL-centric; incompatible with tRPC's RPC model. diff --git a/docs/library-decisions/2026-05-14-@testing-library/jest-dom.md b/docs/library-decisions/2026-05-14-@testing-library/jest-dom.md new file mode 100644 index 0000000..f72fcda --- /dev/null +++ b/docs/library-decisions/2026-05-14-@testing-library/jest-dom.md @@ -0,0 +1,84 @@ +--- +package: "@testing-library/jest-dom" +version: "^6.5.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @testing-library/jest-dom license + - npm view @testing-library/jest-dom version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @testing-library/jest-dom license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@testing-library/jest-dom` ships its own TypeScript declaration files that extend the vitest/jest `expect` matchers. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained by the Testing Library organization. The 6.x line is the current major. Regular releases tracking vitest and jest compatibility. + +## Filter: boundary-fit + + + +`@testing-library/jest-dom` is a dependency of `@repo/core-testing`, which is the workspace's shared testing infrastructure package. Custom DOM matchers (`toBeInTheDocument`, `toHaveTextContent`, etc.) are set up in `core-testing`'s setup file and available to all feature test suites via the `core-testing` dependency. This is the correct placement. + +## Filter: shadow-check + + + +`@testing-library/jest-dom` is the sole custom DOM matcher extension in the workspace. No competing matcher library is present. + +## Filter: eu-residency + + + +`@testing-library/jest-dom` is a test utility library with no network communication. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@testing-library/jest-dom` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `@testing-library/jest-dom` to set up custom DOM assertion matchers. Feature packages that render React components in tests use these matchers via `core-testing`. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@testing-library/jest-dom` extends vitest's `expect` with semantic DOM matchers, replacing brittle assertion patterns like `expect(el.innerHTML).toContain('text')` with `expect(el).toHaveTextContent('text')`. + +## Prompt: migration-cost-out + +Low. `@testing-library/jest-dom` is configured in one setup file in `@repo/core-testing`. Removing it requires updating that setup and replacing any DOM-specific matchers in test files with lower-level assertions. + +## Prompt: alternatives-considered + +1. **Plain vitest `expect` matchers only** — Viable but produces less readable test assertions for DOM state; `toBeInTheDocument()` is significantly clearer than checking element existence manually. +2. **`@vitest/ui` accessibility assertions** — Narrower scope; `@testing-library/jest-dom` covers the full semantic DOM assertion surface. diff --git a/docs/library-decisions/2026-05-14-@testing-library/react.md b/docs/library-decisions/2026-05-14-@testing-library/react.md new file mode 100644 index 0000000..f72fe7f --- /dev/null +++ b/docs/library-decisions/2026-05-14-@testing-library/react.md @@ -0,0 +1,84 @@ +--- +package: "@testing-library/react" +version: "^16.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @testing-library/react license + - npm view @testing-library/react version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @testing-library/react license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@testing-library/react` ships its own TypeScript declaration files. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained by the Testing Library organization. The 16.x line targets React 19. Regular releases; strong community and ecosystem adoption. + +## Filter: boundary-fit + + + +`@testing-library/react` is a dependency of `@repo/core-testing`, the workspace's shared testing infrastructure. It provides `render`, `screen`, `fireEvent`, and related utilities for component tests. Feature packages that test UI components use these utilities via `core-testing`. This is the correct placement for shared test infrastructure. + +## Filter: shadow-check + + + +`@testing-library/react` is the sole React component testing utility in the workspace. No competing library (Enzyme, React Test Renderer) is present. + +## Filter: eu-residency + + + +`@testing-library/react` is a test utility library with no network communication. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@testing-library/react` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `@testing-library/react` to provide the `render` utility and `screen` query API for component tests. Feature packages with UI components use these via `core-testing`. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@testing-library/react` replaces Enzyme and React Test Renderer. Testing Library's philosophy of testing from the user's perspective (querying by role, label, text) produces more resilient tests than implementation-detail-aware approaches. + +## Prompt: migration-cost-out + +Hard. `render`, `screen`, `fireEvent`, and `userEvent` APIs from Testing Library are used in all component tests. Migrating to a different testing approach requires rewriting all component tests and changing the query strategy (from accessibility-tree queries to DOM selectors or component internals). + +## Prompt: alternatives-considered + +1. **Enzyme** — Deprecated and no longer maintained for React 18+; Testing Library is the ecosystem standard. +2. **`react-dom/test-utils`** — Lower-level API without the accessibility-query helpers; more verbose and less idiomatic for testing user behavior. diff --git a/docs/library-decisions/2026-05-14-@testing-library/user-event.md b/docs/library-decisions/2026-05-14-@testing-library/user-event.md new file mode 100644 index 0000000..3040446 --- /dev/null +++ b/docs/library-decisions/2026-05-14-@testing-library/user-event.md @@ -0,0 +1,84 @@ +--- +package: "@testing-library/user-event" +version: "^14.5.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @testing-library/user-event license + - npm view @testing-library/user-event version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @testing-library/user-event license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@testing-library/user-event` ships its own TypeScript declaration files. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained by the Testing Library organization. The 14.x line is the current major. Regular releases. + +## Filter: boundary-fit + + + +`@testing-library/user-event` is a dependency of `@repo/core-testing`, the workspace's shared testing infrastructure. It provides realistic user interaction simulation (`userEvent.click`, `userEvent.type`, etc.) that more accurately models browser behavior than `fireEvent`. This is the correct placement for shared test infrastructure. + +## Filter: shadow-check + + + +`@testing-library/user-event` is the sole user interaction simulation library in the workspace. No competing library is present. + +## Filter: eu-residency + + + +`@testing-library/user-event` is a test utility library with no network communication. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@testing-library/user-event` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `@testing-library/user-event` to provide realistic interaction utilities for component tests. Feature packages with interactive UI components use these via `core-testing`. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@testing-library/user-event` replaces `@testing-library/dom`'s `fireEvent` for interaction tests. `userEvent` simulates the full browser event sequence (pointerdown → mousedown → focus → click → pointerup → mouseup) rather than dispatching a single synthetic event, producing more faithful integration tests. + +## Prompt: migration-cost-out + +Low. `@testing-library/user-event` is used in component tests alongside `@testing-library/react`. Removing it requires downgrading interaction tests to `fireEvent` calls — a mechanical change but a loss of test fidelity. + +## Prompt: alternatives-considered + +1. **`fireEvent` only** — Simpler but fires only one synthetic event per interaction; misses focus/blur and keyboard event sequences that real browsers emit. +2. **Playwright component testing** — Full browser testing is reserved for e2e (`pnpm test:e2e`); `userEvent` is the right tool for unit/integration component tests. diff --git a/docs/library-decisions/2026-05-14-@trpc/client.md b/docs/library-decisions/2026-05-14-@trpc/client.md new file mode 100644 index 0000000..ab1f0f3 --- /dev/null +++ b/docs/library-decisions/2026-05-14-@trpc/client.md @@ -0,0 +1,84 @@ +--- +package: "@trpc/client" +version: "^11.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @trpc/client license + - npm view @trpc/client version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @trpc/client license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@trpc/client` is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained alongside `@trpc/server` by the tRPC team. Versioned and released together with the server package. + +## Filter: boundary-fit + + + +`@trpc/client` is used in `@repo/core-testing` to provide a mock tRPC client for test setups. This is the correct tier for test infrastructure utilities. No boundary rule restricts `@trpc/client` usage here. + +## Filter: shadow-check + + + +`@trpc/client` is the sole tRPC client implementation in the workspace. No competing client adapter is present. + +## Filter: eu-residency + + + +`@trpc/client` is a pure client-side RPC library with no vendor-controlled network endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@trpc/client` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `@trpc/client` to build the mock tRPC client used in integration test setups. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`@trpc/client` is the natural companion to `@trpc/server`; no alternative client approach was evaluated separately. Using `@trpc/client` ensures the test setup mirrors the production client configuration. + +## Prompt: migration-cost-out + +Low. `@trpc/client` is confined to `@repo/core-testing`'s test utilities. Migrating out requires updating the mock client setup in one package. Feature packages reference tRPC types from `@trpc/server`, not `@trpc/client`. + +## Prompt: alternatives-considered + +1. **Direct HTTP fetch in tests** — Rejected: bypasses tRPC middleware and type inference, making tests less representative of real client behavior. +2. **`@trpc/server` `createCaller` (server-side calling)** — Valid alternative for pure unit tests; `@trpc/client` is used where the test needs to exercise the actual HTTP transport or client link chain. diff --git a/docs/library-decisions/2026-05-14-@trpc/server.md b/docs/library-decisions/2026-05-14-@trpc/server.md new file mode 100644 index 0000000..e2668ee --- /dev/null +++ b/docs/library-decisions/2026-05-14-@trpc/server.md @@ -0,0 +1,84 @@ +--- +package: "@trpc/server" +version: "^11.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view @trpc/server license + - npm view @trpc/server version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view @trpc/server license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`@trpc/server` is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/` package is needed. + +## Filter: maintenance + + + +Actively maintained by the tRPC team. The 11.x line is the current major. Regular releases; strong community adoption in the Next.js ecosystem. + +## Filter: boundary-fit + + + +`@trpc/server` is the workspace-standard RPC layer for type-safe client-server communication (ADR-019 references tRPC as the transport for use-case exposure). Feature packages export their tRPC routers; `core-api` aggregates them; apps mount the root router. Feature packages own their error middleware (`integrations/api/procedures.ts`). No boundary rule restricts `@trpc/server` to a specific tier. + +## Filter: shadow-check + + + +`@trpc/server` is the sole RPC framework in the workspace. No competing API layer (REST, GraphQL, gRPC) is present for the same purpose. + +## Filter: eu-residency + + + +`@trpc/server` is a pure server-side routing library with no network communication to vendor-controlled endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `@trpc/server` at the time of this trace. + +## Filter: named-consumer + + + +All five feature packages export a tRPC router that uses `@trpc/server`. `@repo/core-api` aggregates these routers. `@repo/core-shared` provides the tRPC base instance and error middleware utilities. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +`@trpc/server` replaces a hypothetical hand-written REST API layer. tRPC enables end-to-end type safety between the server use cases and the Next.js client without a separate OpenAPI spec or code generation step. + +## Prompt: migration-cost-out + +Hard. tRPC router types propagate from the server to the client via TypeScript inference. Every feature package's tRPC router, the root `AppRouter` type in `core-api`, and every client-side query in the apps reference `@trpc/server` types. Migrating to REST would require replacing all router definitions, regenerating types (e.g., via OpenAPI), and updating all client call sites. + +## Prompt: alternatives-considered + +1. **GraphQL (Apollo/Pothos)** — More complex schema layer required; the resolver pattern does not map cleanly onto the factory-function use-case pattern mandated by CLAUDE.md. +2. **OpenAPI + Zodios** — Requires a separate schema definition step and code generation; tRPC's type inference is more direct for a monorepo where client and server share the same TypeScript project. diff --git a/docs/library-decisions/2026-05-14-globals.md b/docs/library-decisions/2026-05-14-globals.md new file mode 100644 index 0000000..760e3d9 --- /dev/null +++ b/docs/library-decisions/2026-05-14-globals.md @@ -0,0 +1,84 @@ +--- +package: globals +version: "^17.6.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view globals license + - npm view globals version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view globals license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`globals` ships its own TypeScript declaration files. No separate `@types/globals` package is needed. + +## Filter: maintenance + + + +Maintained by the Sindre Sorhus ecosystem. Regularly updated to track ECMAScript specification changes and new browser/Node.js globals. Last release < 18 months. + +## Filter: boundary-fit + + + +`globals` is a dependency of `@repo/core-eslint`, the shared ESLint configuration package. It provides the global variable definitions consumed by ESLint's `languageOptions.globals` configuration. This is the correct placement for a configuration-layer utility. + +## Filter: shadow-check + + + +`globals` is the de-facto standard globals catalog for ESLint configurations. No competing globals package is present in the workspace. + +## Filter: eu-residency + + + +`globals` is a static data package (JSON + TypeScript types) with no network communication. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `globals` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-eslint` uses `globals` in its ESLint flat-config exports to declare browser and Node.js global environments. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`globals` replaces the deprecated `env` configuration approach in ESLint's legacy config format. In the flat config system, `languageOptions.globals` with the `globals` package is the recommended approach. + +## Prompt: migration-cost-out + +Mechanical. `globals` is used in one configuration file (`@repo/core-eslint`). Migrating to a different globals source requires updating that file only. + +## Prompt: alternatives-considered + +1. **Inline global declarations** — Verbose and maintenance-heavy; the `globals` package is the ESLint ecosystem standard for this purpose. +2. **`@types/node` globals only** — Insufficient for browser environments; `globals` covers both environments cleanly. diff --git a/docs/library-decisions/2026-05-14-payload.md b/docs/library-decisions/2026-05-14-payload.md new file mode 100644 index 0000000..27a034a --- /dev/null +++ b/docs/library-decisions/2026-05-14-payload.md @@ -0,0 +1,84 @@ +--- +package: payload +version: "^3.14.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: self-hostable + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view payload license + - npm view payload version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view payload license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +Payload CMS is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/payload` package is needed. + +## Filter: maintenance + + + +Actively maintained by the Payload CMS team. The 3.x line is the current major and receives regular releases. Last release < 18 months, active issue tracker. + +## Filter: boundary-fit + + + +Payload CMS is the workspace CMS and repository backend. Feature packages (`@repo/auth`, `@repo/blog`, etc.) use Payload as the data layer via the repository pattern (ADR-002). `core-cms` and `core-shared` use Payload directly. ESLint boundary rules restrict direct Payload queries to repository implementations only — feature packages MUST NOT call `payload.*` outside their repository files. + +## Filter: shadow-check + + + +Payload is the sole CMS and ORM-like data layer in the workspace. No competing headless CMS or database abstraction (Strapi, Sanity, Prisma, etc.) is present or proposed. + +## Filter: eu-residency + + + +Payload CMS is a fully self-hosted solution. No data is transmitted to Payload-controlled endpoints at runtime. EU residency is inherent; the deployment environment controls data location. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `payload` at the time of this trace. + +## Filter: named-consumer + + + +All five feature packages (`@repo/auth`, `@repo/blog`, `@repo/media`, `@repo/marketing-pages`, `@repo/navigation`) use Payload for repository access. `@repo/core-cms` configures the Payload instance. `@repo/core-shared` receives Payload config at constructor time. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +Payload CMS replaces hand-rolled REST API + ORM patterns that would require maintaining a separate data layer, schema migrations, and admin UI from scratch. No parallel CMS is running. + +## Prompt: migration-cost-out + +Hard. Payload is the data store for all content (articles, users, media, navigation). Migrating out requires replacing every repository implementation across five feature packages, the CMS configuration in `core-cms`, the admin UI, and all database schema definitions. The repository interface boundary (ADR-002) limits the feature-layer surface to repository implementations only, reducing blast radius, but the volume and data-format dependencies make migration substantial. + +## Prompt: alternatives-considered + +1. **Strapi** — Evaluated but rejected; weaker TypeScript support at the time and less flexible content modeling for mixed structured + rich-text content. +2. **Sanity** — SaaS-first model raises EU residency concerns without a self-hosted plan; Payload's self-hosted model is a better fit for the compliance profile. diff --git a/docs/library-decisions/2026-05-14-react-dom.md b/docs/library-decisions/2026-05-14-react-dom.md new file mode 100644 index 0000000..e51bdf2 --- /dev/null +++ b/docs/library-decisions/2026-05-14-react-dom.md @@ -0,0 +1,84 @@ +--- +package: react-dom +version: "^19.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view react-dom license + - npm view react-dom version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view react-dom license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +`react-dom` ships its own TypeScript declaration files in React 19. No separate `@types/react-dom` package is required at runtime. + +## Filter: maintenance + + + +Actively maintained by Meta alongside `react`. Versioned and released together with the React core package. + +## Filter: boundary-fit + + + +`react-dom` is a dependency of `@repo/core-testing` to enable DOM-based React component rendering via `@testing-library/react`. No boundary rule restricts `react-dom` usage in the testing tier. + +## Filter: shadow-check + + + +`react-dom` is the sole React DOM renderer in the workspace. No competing renderer (react-native, react-three-fiber, etc.) targets the same DOM environment. + +## Filter: eu-residency + + + +`react-dom` is a pure runtime library for DOM rendering with no network communication. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `react-dom` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `react-dom` as a peer dependency for `@testing-library/react` DOM rendering. Named, non-hypothetical consumer exists today. + +## Prompt: replaces + +`react-dom` is the mandatory companion to `react` for web rendering; no alternative was evaluated separately. + +## Prompt: migration-cost-out + +Impossible. `react-dom` is the DOM rendering layer for all React components in the workspace. Replacing it would require migrating to a different renderer or framework simultaneously with React. + +## Prompt: alternatives-considered + +1. **`react-dom/server` only** — Insufficient: the testing layer requires the full DOM renderer for `@testing-library/react`. +2. **No alternatives applicable** — `react-dom` is the only DOM renderer for React; the choice is inherent to the React framework selection. diff --git a/docs/library-decisions/2026-05-14-react.md b/docs/library-decisions/2026-05-14-react.md new file mode 100644 index 0000000..8a1b783 --- /dev/null +++ b/docs/library-decisions/2026-05-14-react.md @@ -0,0 +1,84 @@ +--- +package: react +version: "^19.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view react license + - npm view react version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view react license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +React 19 ships its own TypeScript declaration files bundled in the package. No separate `@types/react` package is required at runtime (though `@types/react` is still used as a devDependency for type-checking in some packages). + +## Filter: maintenance + + + +Actively maintained by Meta. React 19 is the current stable major release. Long-term support commitment from Meta; used in production by millions of applications. + +## Filter: boundary-fit + + + +`react` is a dependency of `@repo/core-testing` to support React component rendering in test environments via `@testing-library/react`. The Next.js and TanStack Start apps consume React through their framework packages. No boundary rule restricts React usage in the testing tier. + +## Filter: shadow-check + + + +React is the sole UI rendering library in the workspace. No competing component library (Vue, Svelte, Solid, etc.) is present. + +## Filter: eu-residency + + + +`react` is a pure runtime library for UI rendering with no network communication to vendor-controlled endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `react` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` uses `react` as a peer for `@testing-library/react`. The Next.js and TanStack Start apps consume React through their framework layers. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +React replaces no prior UI framework — it is the founding choice for the web layer of this monorepo. + +## Prompt: migration-cost-out + +Impossible. React's component model and JSX syntax are used throughout both frontend apps and the testing layer. Replacing React would require rewriting all UI components, routing layers, and testing utilities across two apps. + +## Prompt: alternatives-considered + +1. **Vue** — Different component model; incompatible with the Next.js and tRPC ecosystem choices made at project inception. +2. **Solid** — Excellent performance characteristics but smaller ecosystem; Next.js and the established tRPC/React Query integration made React the pragmatic choice. diff --git a/docs/library-decisions/2026-05-14-superjson.md b/docs/library-decisions/2026-05-14-superjson.md new file mode 100644 index 0000000..ce4385b --- /dev/null +++ b/docs/library-decisions/2026-05-14-superjson.md @@ -0,0 +1,84 @@ +--- +package: superjson +version: "^2.2.1" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view superjson license + - npm view superjson version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view superjson license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +superjson is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/superjson` package is needed. + +## Filter: maintenance + + + +Actively maintained. Last release < 18 months. Used widely in the tRPC and Next.js ecosystem. + +## Filter: boundary-fit + + + +superjson is the serialization transformer used by the tRPC layer (`@repo/core-shared`) to handle non-JSON-serializable types (Dates, Maps, Sets) over the wire. `core-testing` uses it for mock tRPC client setup. No boundary rules restrict superjson to a specific tier. + +## Filter: shadow-check + + + +superjson is the sole tRPC-compatible serialization transformer in the workspace. No competing serializer (devalue, msgpackr, etc.) is present. + +## Filter: eu-residency + + + +superjson is a pure serialization library with no network communication, telemetry, or data transmission. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `superjson` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-shared` uses superjson as the tRPC transformer. `@repo/core-testing` uses superjson for mock tRPC client configuration. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +superjson replaces the default JSON-only serialization in tRPC, which would fail silently when Date objects or other non-JSON types are passed through procedure calls. + +## Prompt: migration-cost-out + +Low. superjson is used as the `transformer` option in the tRPC router and client configuration — two call sites in `core-shared`. Replacing it requires swapping the transformer and ensuring the replacement handles the same non-JSON types. No feature package references superjson directly. + +## Prompt: alternatives-considered + +1. **devalue** — Supports more types but is less mature in the tRPC ecosystem; superjson is the de-facto tRPC transformer standard. +2. **JSON-only (no transformer)** — Rejected because it silently loses type fidelity for Dates and breaks any use case that returns or receives a `Date` value. diff --git a/docs/library-decisions/2026-05-14-vitest.md b/docs/library-decisions/2026-05-14-vitest.md new file mode 100644 index 0000000..778250f --- /dev/null +++ b/docs/library-decisions/2026-05-14-vitest.md @@ -0,0 +1,84 @@ +--- +package: vitest +version: "^3.0.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view vitest license + - npm view vitest version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view vitest license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +vitest is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/vitest` package is needed. + +## Filter: maintenance + + + +Actively maintained by the Vite / Vitest team. The 3.x line is the current major. Regular releases with strong community momentum in the Vite ecosystem. + +## Filter: boundary-fit + + + +vitest is listed as a runtime dependency of `@repo/core-testing` because it provides the test runner APIs (`describe`, `it`, `expect`, `vi`) that `core-testing` re-exports or uses in its test utilities. All feature packages declare `vitest` as a devDependency. This is the correct placement for a testing infrastructure package. + +## Filter: shadow-check + + + +vitest is the sole test runner in the workspace. No competing runner (Jest, Jasmine, Mocha) is present. + +## Filter: eu-residency + + + +vitest is a local test runner with no network communication to vendor-controlled endpoints. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `vitest` at the time of this trace. + +## Filter: named-consumer + + + +`@repo/core-testing` lists vitest as a runtime dependency. Every feature package uses vitest as a devDependency for running tests. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +vitest replaces Jest as the test runner. The Vite-based transformation pipeline eliminates the need for Babel transforms and provides native ES module support, reducing test suite configuration complexity. + +## Prompt: migration-cost-out + +Hard. vitest's `describe` / `it` / `expect` / `vi.fn()` APIs are used in every test file across all packages. Migrating to Jest or another runner requires updating all test files (largely mechanical API renames) and reconfiguring the coverage pipeline (ADR-020 L0 thresholds, `@vitest/coverage-v8`). + +## Prompt: alternatives-considered + +1. **Jest** — Mature but requires additional Babel/ESM configuration in a Vite-based monorepo; vitest provides native compatibility. +2. **Node.js `node:test`** — Lightweight but lacks the ecosystem integrations (coverage, snapshot, mocking) that vitest provides out of the box. diff --git a/docs/library-decisions/2026-05-14-zod.md b/docs/library-decisions/2026-05-14-zod.md new file mode 100644 index 0000000..9b02746 --- /dev/null +++ b/docs/library-decisions/2026-05-14-zod.md @@ -0,0 +1,84 @@ +--- +package: zod +version: "^3.24.0" +tier: core +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: null +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view zod license + - npm view zod version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view zod license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +Zod is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/zod` package is needed. + +## Filter: maintenance + + + +Actively maintained. The 3.x line is the current stable major. Regular releases; the zod 4.x release is in active development. Strong community and ecosystem. + +## Filter: boundary-fit + + + +Zod is the workspace-standard schema validation library. Every use case exports `xInputSchema` and `xOutputSchema` as `z.ZodObject` instances (CLAUDE.md Key Conventions). Feature packages, core packages, and the tRPC layer all use Zod for input validation and output parsing. No boundary rules restrict Zod to a specific tier. + +## Filter: shadow-check + + + +Zod is the sole schema validation library in the workspace. No competing validator (Valibot, Yup, Joi, etc.) is present or proposed. The `shadow-check` filter from `_template.md` explicitly names Zod as a workspace-locked library. + +## Filter: eu-residency + + + +Zod is a pure runtime validation library with no network communication, telemetry, or data transmission. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against `zod` at the time of this trace. + +## Filter: named-consumer + + + +All five feature packages use Zod for use-case input/output schemas. `core-shared` uses Zod for tRPC input validation and error schemas. `core-audit` uses Zod for audit event schemas. Named, non-hypothetical consumers exist today. + +## Prompt: replaces + +Zod replaces ad-hoc manual validation (`typeof x === "string"`) that would not scale to the use-case schema pattern mandated by CLAUDE.md. No prior schema library was in the workspace. + +## Prompt: migration-cost-out + +Hard. Zod's `z.ZodObject` types are woven into the public API surface of every use case (`xInputSchema`, `xOutputSchema`, `IXUseCase`). The tRPC router layer reads Zod schemas directly. Migrating out would require replacing schema definitions across all feature packages, updating the tRPC integration, and touching the conformance ESLint rules that reference Zod types. + +## Prompt: alternatives-considered + +1. **Valibot** — Smaller bundle size but at the time of adoption had less mature TypeScript inference for the factory-function use-case pattern. +2. **Manual `typeof` / JSON Schema** — Zero dependency but does not produce TypeScript types automatically; incompatible with the `xInputSchema`/`xOutputSchema` contract pattern.