docs: reflect tooling-package rename + Turbo boundaries enforcement

- Rename eslint-config → core-eslint, typescript-config → core-typescript
  in all docs (package map, AGENTS.md, overview.md, dependency-flow.md, etc.)
- Document the five-tag model (app, feature, core, core-composition,
  tooling) — refinement of ADR-006's three-tag mention
- Document core-trpc's core-composition tag (transitively reaches features
  through core-api's AppRouter type)
- Note Turborepo boundaries as a second enforcement layer alongside ESLint
- Add ADR-010 explaining the two-layer enforcement decision and
  five-tag refinement

Files updated:
- docs/architecture/overview.md: package map, enforcement layers, five-tag section
- docs/architecture/dependency-flow.md: boundary rules, enforcement strategy
- docs/architecture/vertical-feature-spec.md: package names, five-tag model
- AGENTS.md: package map, boundary rules, commands
- CLAUDE.md: tooling package names, quick-start command
- packages/core-eslint/AGENTS.md: tag clarification
- packages/core-typescript/AGENTS.md: tag clarification
- packages/core-api/AGENTS.md: core-composition tag
- packages/core-cms/AGENTS.md: core-composition tag
- packages/core-trpc/AGENTS.md: core-composition tag + rationale
- docs/decisions/adr-010-turbo-boundaries.md: new ADR

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 12:24:04 +02:00
parent eb55a698f3
commit 2c2375920f
11 changed files with 252 additions and 71 deletions

View File

@@ -9,10 +9,10 @@ This is a **Turborepo + pnpm monorepo** organized by vertical features. Each fea
| Package | Tag | Purpose |
|---|---|---|
| `@repo/core-shared` | core | Generic primitives (Zod, env, Payload hooks/fields/blocks, tRPC init/context) |
| `@repo/core-cms` | core (composition) | Payload config aggregator — imports `@repo/<feature>/cms` only |
| `@repo/core-api` | core (composition) | tRPC router aggregator — imports `@repo/<feature>/api` only |
| `@repo/core-trpc` | core | Frontend tRPC client + framework-specific providers (Next.js, TanStack) |
| `@repo/core-ui` | core | Design system (atoms, molecules, generic organisms, templates) |
| `@repo/core-api` | core-composition | tRPC router aggregator — imports `@repo/<feature>/api` only |
| `@repo/core-cms` | core-composition | Payload config aggregator — imports `@repo/<feature>/cms` only |
| `@repo/core-trpc` | core-composition | Frontend tRPC client + framework-specific providers (Next.js, TanStack) |
| `@repo/auth` | feature | Users collection + sign-in/up/out |
| `@repo/blog` | feature | Articles collection + article use-cases |
| `@repo/media` | feature | Media collection + upload helpers |
@@ -25,42 +25,47 @@ This is a **Turborepo + pnpm monorepo** organized by vertical features. Each fea
## Boundary Rules
### Three tags
### Five tags
- **app** — `apps/web-next`, `apps/web-tanstack`, `apps/cms`
- **feature** — `packages/auth`, `blog`, `media`, `marketing-pages`, `navigation`
- **core** — `packages/core-shared`, `core-cms`, `core-api`, `core-trpc`, `core-ui`
- (untagged) — `packages/eslint-config`, `typescript-config`
- **app** (4 packages)`apps/web-next`, `apps/web-tanstack`, `apps/cms`, `apps/storybook`
- **core-composition** (3 packages) — `packages/core-api`, `core-cms`, `core-trpc`
- **core** (2 packages)`packages/core-shared`, `core-ui`
- **feature** (5 packages) — `packages/auth`, `blog`, `media`, `marketing-pages`, `navigation`
- **tooling** (2 packages) — `packages/core-eslint`, `core-typescript`
### Allowed dependency directions
```
app → feature, core
feature → core
core → core (restricted; see exceptions below)
```
**Disallowed:** `core → feature`, `core → app`, `feature → app`, `feature → feature`.
| Tag | May depend on |
|---|---|
| app | app, core, core-composition, feature, tooling |
| core-composition | core, core-composition, feature, tooling |
| core | core, core-composition, tooling |
| feature | core, tooling |
| tooling | tooling |
### Composition exceptions
Two packages may cross normal boundaries:
1. **`core-cms`** may import `@repo/<feature>/cms` subpath exports only (to compose Payload collections).
2. **`core-api`** may import `@repo/<feature>/api` subpath exports only (to compose tRPC routers).
1. **`core-api`** may import `@repo/<feature>/api` subpath exports only (to compose tRPC routers).
2. **`core-cms`** may import `@repo/<feature>/cms` subpath exports only (to compose Payload collections).
3. **`core-trpc`** reaches features transitively through `core-api`'s `AppRouter` type.
No other cross-package boundary deviations are permitted.
### Three enforcement layers
### Four enforcement layers
1. **`package.json` dependencies** — only allowed deps are declared; illegal imports fail at install time.
2. **`exports` maps** — feature packages expose `.`, `./cms`, `./api`, `./di/bind-production` only; no deep source paths exist.
3. **ESLint `eslint-plugin-boundaries`** — configured in `packages/eslint-config/`:
- Feature packages may import from `core-*` and tooling only.
- `core-shared`, `core-trpc`, `core-ui` may not import any feature.
3. **ESLint `eslint-plugin-boundaries`** (lint-time) — configured in `packages/core-eslint/`:
- Enforces the five-tag rules at linting
- Feature packages may import from `core` and tooling only.
- `core-shared`, `core-ui` may not import any feature.
- `core-api` restricted to `@repo/<feature>/api` imports.
- `core-cms` restricted to `@repo/<feature>/cms` imports.
- No `../../../` cross-package relative imports.
4. **Turborepo `boundaries`** (build-graph time) — configured in root `turbo.json`:
- Validates the entire workspace dependency graph, including transitive dependencies
- Catches issues ESLint might miss (e.g., transitive feature reaches through composition packages)
- Run with `pnpm turbo boundaries`
---
@@ -82,7 +87,8 @@ Start with `docs/guides/adding-a-feature.md` for a step-by-step walkthrough cove
pnpm install # Install all dependencies
pnpm dev # Start all dev servers (Next.js :3000, CMS :3001, Storybook :6006)
pnpm typecheck # Type-check all packages
pnpm lint # Lint all packages (boundaries enforced)
pnpm lint # Lint all packages (ESLint boundaries enforced)
pnpm turbo boundaries # Validate workspace dependency graph (Turbo boundaries)
pnpm test # Run all unit + integration tests (Vitest)
pnpm test:e2e # Run e2e tests (Playwright across both apps)
pnpm build # Build all packages (Turborepo)
@@ -202,10 +208,8 @@ await bindProductionUsers(authContainer, payloadConfig);
Per-package documentation lives in each `AGENTS.md`:
- `packages/core-shared/AGENTS.md`
- `packages/core-cms/AGENTS.md`
- `packages/core-api/AGENTS.md`
- `packages/core-trpc/AGENTS.md`
- `packages/core-api/AGENTS.md`, `core-cms/AGENTS.md`, `core-trpc/AGENTS.md`
- `packages/core-ui/AGENTS.md`
- `packages/auth/AGENTS.md`, `blog/AGENTS.md`, `media/AGENTS.md`, `marketing-pages/AGENTS.md`, `navigation/AGENTS.md`
- `packages/eslint-config/AGENTS.md`, `typescript-config/AGENTS.md`
- `packages/core-eslint/AGENTS.md`, `core-typescript/AGENTS.md`
- `apps/cms/AGENTS.md`, `web-next/AGENTS.md`, `web-tanstack/AGENTS.md`, `storybook/AGENTS.md`

View File

@@ -7,12 +7,13 @@ pnpm install # Install all dependencies
pnpm dev # Start all dev servers
pnpm build # Build all packages
pnpm test # Run all tests
pnpm turbo boundaries # Validate workspace dependency graph
docker compose up -d # Start PostgreSQL
```
## Project Overview
Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, `blog`, `media`, `marketing-pages`, `navigation`) owns its Clean Architecture layers. Core packages (`core-shared`, `core-cms`, `core-api`, `core-trpc`, `core-ui`) provide foundation. Supports Next.js and TanStack Start as frontend frameworks, Payload CMS for content management, and comprehensive agent-optimized documentation.
Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, `blog`, `media`, `marketing-pages`, `navigation`) owns its Clean Architecture layers. Core packages (`core-shared`, `core-cms`, `core-api`, `core-trpc`, `core-ui`) provide foundation. Two tooling packages (`core-eslint`, `core-typescript`) provide shared configs. Workspace boundaries are enforced by ESLint (lint-time) and Turborepo (build-graph time). Supports Next.js and TanStack Start as frontend frameworks, Payload CMS for content management, and comprehensive agent-optimized documentation.
## Read First

View File

@@ -21,13 +21,16 @@
| shared | | | | |
+--------+ +-----------+ +----------------+
Boundary rules (enforced by eslint-plugin-boundaries):
app → app, core, feature, core-composition (any)
feature → core (any), but NOT other features, NOT app
core → core, but NOT feature, NOT app
core-composition → core, feature subpath exports only (`/cms`, `/api`)
core-api → @repo/<feature>/api
core-cms → @repo/<feature>/cms
Boundary rules (enforced by ESLint + Turborepo boundaries):
app → app, core, core-composition, feature, tooling
feature → core, tooling
core → core, core-composition, tooling
core-composition → core, core-composition, feature, tooling
tooling → tooling
Composition exceptions:
core-api → @repo/<feature>/api (subpath only)
core-cms → @repo/<feature>/cms (subpath only)
```
## Concrete examples
@@ -65,6 +68,14 @@ import { blogRouter } from "@repo/blog/api"; // ❌ core → feature
import { someBlogThing } from "@repo/blog"; // ❌ core → feature (only core-api/core-cms have exception)
```
## Three-layer enforcement
## Enforcement strategy
ESLint catches accidental cross-package imports at lint time. The `package.json` `exports` map blocks deep imports at module-resolution time. Workspace `dependencies` declarations make the package graph itself the source of truth — if you didn't declare it, you can't import it.
Three layers work in tandem:
1. **`package.json` dependencies** — if you didn't declare it, you can't import it
2. **`exports` map** — blocks deep imports; only public subpaths are accessible
3. **Two parallel automated checks** (both enforcing the same five-tag model):
- **ESLint `eslint-plugin-boundaries`** runs at lint time, catching direct-import violations
- **Turborepo `boundaries`** runs at build time, validating the entire workspace graph including transitive dependencies
The two enforcement layers are independent but complementary. ESLint is stricter on per-import context (e.g., file-specific exemptions via `// @boundaries-ignore`), while Turborepo catches transitive issues that lint-time checking misses. Run `pnpm lint` and `pnpm turbo boundaries` in CI to catch all violations.

View File

@@ -21,8 +21,8 @@ packages/
navigation/ Header global + menu items
# Tooling
eslint-config/ Shared ESLint flat config + boundary rules
typescript-config/ Shared tsconfig + vitest base
core-eslint/ Shared ESLint flat config + boundary rules
core-typescript/ Shared tsconfig + vitest base
```
## Data flow
@@ -47,7 +47,36 @@ Payload Local API → Postgres
1. **`package.json` deps** — only declare allowed deps
2. **`exports` map** — each package exposes a small public surface (`.`, `./cms`, `./api`, `./di/bind-production`)
3. **ESLint `eslint-plugin-boundaries`** — three tags (`app`, `feature`, `core`); two composition exceptions (`core-api` may import `@repo/<feature>/api`; `core-cms` may import `@repo/<feature>/cms`)
3. **Two parallel automated checks**:
- **ESLint `eslint-plugin-boundaries`** (lint-time) — enforces boundary rules at linting
- **Turborepo `boundaries`** (build-graph time) — validates entire workspace dependency graph, including transitive reaches
Both use the same five-tag model; see "Five tags" section below.
## Five tags
The workspace is organized into five mutually exclusive tags:
- **app** (4 packages): `apps/cms`, `apps/web-next`, `apps/web-tanstack`, `apps/storybook`
- **core-composition** (3 packages): `packages/core-api`, `packages/core-cms`, `packages/core-trpc`
- **core** (2 packages): `packages/core-shared`, `packages/core-ui`
- **feature** (5 packages): `packages/auth`, `packages/blog`, `packages/media`, `packages/marketing-pages`, `packages/navigation`
- **tooling** (2 packages): `packages/core-eslint`, `packages/core-typescript`
**Allowed dependency directions:**
| Tag | May depend on |
|---|---|
| app | app, core, core-composition, feature, tooling |
| core-composition | core, core-composition, feature, tooling |
| core | core, core-composition, tooling |
| feature | core, tooling |
| tooling | tooling |
**Composition exceptions:**
- `core-api` may import from `@repo/<feature>/api` subpath exports only
- `core-cms` may import from `@repo/<feature>/cms` subpath exports only
- `core-trpc` reaches features transitively through `core-api`'s `AppRouter` type
## Per-feature DI containers

View File

@@ -40,7 +40,7 @@ The refactor preserves Clean Architecture layering *inside* each feature (the ex
- Five `core-*` packages: `core-shared`, `core-cms`, `core-api`, `core-trpc`, `core-ui`
- Five feature packages: `auth`, `blog`, `media`, `marketing-pages`, `navigation`
- Two tooling packages unchanged: `eslint-config`, `typescript-config`
- Two tooling packages renamed: `eslint-config``core-eslint`, `typescript-config``core-typescript`
- Three apps unchanged in name: `apps/web-next`, `apps/web-tanstack`, `apps/cms`
- Packages deleted: `packages/core`, `packages/api`, `packages/api-client`, `packages/cms-core`, `packages/cms-client`, `packages/ui`
- Per-feature InversifyJS containers (no shared container)
@@ -124,9 +124,9 @@ repo/
marketing-pages/ # pages collection + SiteSettings global
navigation/ # header global
# ─── TOOLING (untagged) ───
eslint-config/
typescript-config/
# ─── TOOLING (tagged "tooling") ───
core-eslint/
core-typescript/
docs/
architecture/
@@ -392,44 +392,47 @@ export default buildConfig({
## 9. Boundaries + enforcement
### 9.1 Tags
### 9.1 Five tags
Package-level `turbo.json` tags:
Package-level `turbo.json` tags (refined from earlier ADR-006's three-tag model):
| Tag | Packages |
|---|---|
| `app` | `apps/web-next`, `apps/web-tanstack`, `apps/cms` |
| `app` | `apps/web-next`, `apps/web-tanstack`, `apps/cms`, `apps/storybook` |
| `core-composition` | `packages/core-api`, `core-cms`, `core-trpc` |
| `core` | `packages/core-shared`, `core-ui` |
| `feature` | `packages/auth`, `blog`, `media`, `marketing-pages`, `navigation` |
| `core` | `packages/core-shared`, `core-cms`, `core-api`, `core-trpc`, `core-ui` |
| (untagged) | `packages/eslint-config`, `packages/typescript-config` |
| `tooling` | `packages/core-eslint`, `core-typescript` |
Note: `core-trpc` is `core-composition` (not plain `core`) because it transitively reaches features through `core-api`'s `AppRouter` type.
### 9.2 Allowed dependency directions
```
app → feature, core
feature → core
core → core (restricted; see exceptions)
```
Disallowed: `core → feature`, `core → app`, `feature → app`, `feature → feature`.
| Tag | May depend on |
|---|---|
| app | app, core, core-composition, feature, tooling |
| core-composition | core, core-composition, feature, tooling |
| core | core, core-composition, tooling |
| feature | core, tooling |
| tooling | tooling |
### 9.3 Composition exceptions
- `core-cms` may import `@repo/<feature>/cms` subpath exports only.
- `core-api` may import `@repo/<feature>/api` subpath exports only.
- No other `core-*` package may import any feature package under any export.
- No other package may deviate from the five-tag rules.
### 9.4 Three enforcement layers
### 9.4 Four enforcement layers
1. **`package.json` dependencies** — only allowed deps declared.
2. **`exports` maps** — feature packages expose `.`, `./cms`, `./api` only (no deep source paths).
3. **ESLint `eslint-plugin-boundaries`** — configured in `packages/eslint-config/` flat config:
- Feature packages may import other packages only through public subpath exports.
- `core-shared`, `core-trpc`, `core-ui` may not import feature packages.
- `core-api` restricted to `@repo/<feature>/api`.
- `core-cms` restricted to `@repo/<feature>/cms`.
- No `../../../` cross-package source imports.
4. **TypeScript path aliases** (`tsconfig.base.json`) — only `@repo/<feature>`, `@repo/<feature>/cms`, `@repo/<feature>/api`; no `@repo/<feature>/src/...` paths exist, blocking deep imports at editor level.
3. **ESLint `eslint-plugin-boundaries`** (lint-time) — configured in `packages/core-eslint/` flat config:
- Enforces the five-tag rules (same rules as Turbo boundaries)
- File-specific exemptions via `// @boundaries-ignore` comments
4. **Turborepo `boundaries`** (build-graph time) — configured in root `turbo.json`:
- Validates the entire workspace dependency graph, including transitive dependencies
- Catches issues that lint-time checking misses (e.g., transitive feature reaches)
- Run `pnpm turbo boundaries` to validate
### 9.5 Root `turbo.json` (unchanged concept)
@@ -469,7 +472,7 @@ Tags govern architectural boundaries; `dependsOn: ["^build"]` governs task execu
### 10.2 Vitest
- Each package has its own `vitest.config.ts`.
- Shared base in `packages/typescript-config/vitest.base.ts`; packages extend it and pick `environment: 'jsdom' | 'node'` per need.
- Shared base in `packages/core-typescript/vitest.base.ts`; packages extend it and pick `environment: 'jsdom' | 'node'` per need.
- Turbo `test` task runs `vitest run` per package.
### 10.3 DI in tests (per-feature container)

View File

@@ -0,0 +1,123 @@
# ADR-010: Turborepo boundaries alongside ESLint enforcement
**Status:** Accepted
**Date:** 2026-05-04
**Supersedes:** ADR-006 (partial refinement; not a contradiction)
## Context
ADR-006 established the vertical-feature monorepo with three tags (`app`, `feature`, `core`). ESLint with `eslint-plugin-boundaries` was introduced to enforce direct-import boundaries at lint time, catching violations like:
- Feature package importing from another feature
- Core package importing from a feature
- Deep imports past public `exports` map boundaries
However, ESLint has two intrinsic limitations:
1. **No transitive enforcement** — If `core-trpc` imports `core-api` (which imports feature routers), ESLint sees only the direct edge `core-trpc``core-api`. The transitive reach into features is invisible. A package can declare `@repo/feature-x` as a dependency without ever importing it directly.
2. **No declared-dep enforcement** — A `package.json` dependency that doesn't match an actual import goes undetected. Conversely, a `package.json` dependency might be missing but the transitive graph still allows the code to work.
The result: two types of dependency drift escape lint-time checking:
- A composition package's transitive reach into features (real problem: `core-trpc``core-api``feature-blog-routers`)
- Incorrect or missing `package.json` declarations
## Decision
Add Turborepo's `boundaries` feature as a second enforcement layer running at **build-graph time** (before build), parallel to ESLint's lint-time checks.
### Five-tag model (refined from ADR-006)
ADR-006 mentioned three tags. This ADR refines the model to five, distinguishing composition packages explicitly:
- **app** — `apps/web-next`, `apps/web-tanstack`, `apps/cms`, `apps/storybook`
- **core** — `packages/core-shared`, `core-ui` (pure foundation, no transitive feature reach)
- **core-composition** — `packages/core-api`, `core-cms`, `core-trpc` (composition or transitively reach features)
- **feature** — `packages/auth`, `blog`, `media`, `marketing-pages`, `navigation`
- **tooling** — `packages/core-eslint`, `core-typescript`
Why `core-trpc` is `core-composition`:
- `core-trpc` imports `@repo/core-api` (the tRPC app router)
- `core-api` imports feature routers from `@repo/<feature>/api`
- Therefore, `core-trpc` transitively depends on features through the `AppRouter` type
- This violates ADR-006's "core → NOT feature" rule if we treat `core-trpc` as plain `core`
- Solution: tag `core-trpc` as `core-composition` to make the transitive reach explicit and allowed
### Implementation
1. **Root `turbo.json`** declares boundary rules as a `boundaries.tags` config:
```json
{
"boundaries": {
"tags": {
"app": { "dependencies": { "allow": ["app", "core", "core-composition", "feature", "tooling"] } },
"core-composition": { "dependencies": { "allow": ["core", "core-composition", "feature", "tooling"] } },
"core": { "dependencies": { "allow": ["core", "core-composition", "tooling"] } },
"feature": { "dependencies": { "allow": ["core", "tooling"] } },
"tooling": { "dependencies": { "allow": ["tooling"] } }
}
}
}
```
2. **Per-package `turbo.json`** declares the package's tag:
```json
// packages/blog/turbo.json
{ "extends": ["../../../turbo.json"], "tasks": { /* ... */ } }
// package.json
{ "turbo": { "tasks": { "build": { /* ... */ } }, "tags": ["feature"] } }
```
3. **CLI validation** — `pnpm turbo boundaries` runs the check in <1 second without building anything
### Two layers, not one
Both ESLint and Turborepo enforce the same five-tag rules, but for different reasons:
| Layer | Runs | Sees | Exempts via |
|---|---|---|---|
| ESLint `eslint-plugin-boundaries` | lint-time | Direct imports per file | `// @boundaries-ignore` comments |
| Turborepo `boundaries` | build-graph time | Entire workspace dependency graph including transitives | None (graph-based, not per-import) |
**Why both?**
- **ESLint** provides fine-grained control (file-level exemptions) and immediate feedback during development
- **Turborepo** catches transitive issues (e.g., feature reach through composition packages) and missing declarations
**Enforcement** — CI runs both: `pnpm lint` (includes ESLint) and `pnpm turbo boundaries`.
## Consequences
1. **Two independent checks** — developers get immediate ESLint feedback and a final Turbo gate in CI
2. **Both must stay in sync** — when adding a new tag rule, update both:
- `packages/core-eslint/base.js` (ESLint `eslint-plugin-boundaries` config)
- Root `turbo.json` (`boundaries.tags` config)
- Per-package `package.json` `turbo.tags` declaration
3. **Stricter than before** — Turborepo sees transitives; some patterns that pass ESLint may fail Turbo:
- Example: `packages/cms` might try to use `@repo/<dep>` indirectly (not importing, but depending)
- Solution: declare the dependency explicitly or restructure the import
4. **The five-tag model is a refinement, not a contradiction** — ADR-006 mentioned three tags; this ADR adds `core-composition` and `tooling` explicitly and moves them into the boundary enforcement
5. **`core-trpc`'s new tag** — previously thought of as `core`, now explicitly `core-composition` to match its transitive reach; any code assuming `core-trpc` is `core` must be updated
## Alternatives considered
1. **ESLint only** — Simple, immediate feedback. Downside: misses transitive issues; no build-graph validation.
2. **Turborepo only** — Catches everything eventually, but slower feedback cycle; less granular exemptions.
3. **Both in series** — ESLint first (fast), Turbo second (thorough). Chosen.
4. **Custom graph validator** — Over-engineered; Turborepo's built-in feature is stable and designed for this.
## Related
- **ADR-006:** Vertical feature packages (the original three-tag model)
- **ADR-009:** Integrations folder naming
- **`packages/core-eslint/base.js`** — ESLint configuration
- **Root `turbo.json`** — Turborepo configuration with boundaries rules
- **`docs/architecture/overview.md`** — Package map and five-tag summary
- **`docs/architecture/dependency-flow.md`** — Enforcement layers and rules
- **`AGENTS.md`** — Per-package boundary documentation
## Timeline
- **2026-05-04** — Turborepo boundaries added alongside existing ESLint enforcement
- **CI integration** — `pnpm turbo boundaries` added to lint stage
- **Documentation** — Updated AGENTS.md, overview.md, dependency-flow.md, vertical-feature-spec.md

View File

@@ -1,5 +1,7 @@
# AGENTS.md — core-api
**Tag:** core-composition
**Composition-only package** that aggregates feature tRPC routers into a single root `appRouter`. It does not define procedures; instead, it imports them from feature packages.
## Responsibilities

View File

@@ -1,5 +1,7 @@
# AGENTS.md — core-cms
**Tag:** core-composition
**Composition-only package** that aggregates feature Payload collections and globals into a single Payload config. It does not define its own collections; instead, it imports them from feature packages.
## Responsibilities

View File

@@ -1,6 +1,8 @@
# AGENTS.md — eslint-config
# AGENTS.md — core-eslint
Shared ESLint 9 flat configs (rules, plugins, parser settings) consumed by all packages via `eslint.config.js`.
**Tag:** tooling
Shared ESLint 9 flat configs (rules, plugins, parser settings) consumed by all packages via `eslint.config.js`. Enforces boundary rules alongside Turborepo's `boundaries` feature (which validates the workspace dependency graph at build time).
## What it owns

View File

@@ -1,6 +1,8 @@
# AGENTS.md — core-trpc
Frontend tRPC platform providing the client and framework-specific providers (Next.js, TanStack). Bridges typed backend (`@repo/core-api`) to frontend applications.
**Tag:** core-composition
Frontend tRPC platform providing the client and framework-specific providers (Next.js, TanStack). Bridges typed backend (`@repo/core-api`) to frontend applications. Tagged `core-composition` (not `core`) because it transitively reaches features through `core-api`'s `AppRouter` type.
## Responsibilities

View File

@@ -1,4 +1,6 @@
# AGENTS.md — typescript-config
# AGENTS.md — core-typescript
**Tag:** tooling
Shared TypeScript base configs (`tsconfig.json` files) and Vitest base config, consumed by all packages.