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

@@ -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)