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`