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:
60
AGENTS.md
60
AGENTS.md
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user