feat: add AGENTS.md for all packages and apps (9 files)

This commit is contained in:
2026-04-06 15:04:15 +02:00
parent 95a46fe7f4
commit 2c110b33e9
9 changed files with 255 additions and 0 deletions

18
apps/cms/AGENTS.md Normal file
View File

@@ -0,0 +1,18 @@
# apps/cms — Payload CMS Admin Shell
Thin Next.js shell that imports config from `@repo/cms-core` and serves the Payload admin panel. Contains almost no custom code.
## Rules
- All collections, hooks, globals, and payload.config.ts live in `@repo/cms-core`
- This app only contains Next.js routing boilerplate for the admin panel
- Import `@payload-config` which resolves to `@repo/cms-core/src/payload.config.ts`
- NEVER import from `@repo/core/infrastructure`
## Development
```bash
pnpm dev --filter @repo/cms # Starts on port 3001
```
Requires PostgreSQL running (via `docker compose up postgres`).

24
apps/storybook/AGENTS.md Normal file
View File

@@ -0,0 +1,24 @@
# apps/storybook — Centralized Storybook
Pulls stories from `packages/ui/src/**/*.stories.tsx`. Uses `@storybook/react-vite` with `@tailwindcss/vite` plugin.
## Development
```bash
pnpm dev --filter @repo/storybook # Starts on port 6006
```
## Configuration
- `.storybook/main.ts` — Framework config, story globs, Tailwind vite plugin
- `.storybook/preview.ts` — Global CSS import, control matchers
## Story Organization
Stories are organized by Atomic Design level via title:
- `"Atoms/Button"`, `"Molecules/FormField"`, `"Organisms/DataTable"`
## MCP
When running, Storybook MCP is available at `http://localhost:6006/mcp`.
Install `@storybook/addon-mcp` to enable.

16
apps/web-next/AGENTS.md Normal file
View File

@@ -0,0 +1,16 @@
# apps/web-next — Next.js 15 Reference App
Thin Next.js app consuming `@repo/api-client` for data and `@repo/ui` for components.
## Key Files
- `src/app/api/trpc/[trpc]/route.ts` — tRPC HTTP endpoint (fetch adapter)
- `src/app/providers.tsx` — Wraps with `<ApiProvider>`
- `src/app/layout.tsx` — Root layout
## Rules
- Use `@repo/api-client` hooks for all data fetching
- Use `@repo/ui` components for all UI
- tRPC endpoint imports `appRouter` from `@repo/api`
- Payload instance initialization goes in `src/lib/payload.ts`

View File

@@ -0,0 +1,15 @@
# apps/web-tanstack — TanStack Start Reference App
TanStack Start app consuming `@repo/api-client` for data and `@repo/ui` for components.
## Key Files
- `src/routes/__root.tsx` — Root layout with `<ApiProvider>`
- `src/routes/index.tsx` — Home page
## Rules
- Use `@repo/api-client` hooks for all data fetching
- Use `@repo/ui` components for all UI
- File-based routing via TanStack Router (`src/routes/`)
- Payload instance initialization goes in `src/lib/payload.ts`

View File

@@ -0,0 +1,27 @@
# @repo/api-client — Shared React Query Hooks
Framework-agnostic tRPC + React Query provider consumed by all apps.
## Rules
- NEVER import framework-specific code (no next/, no tanstack/)
- NEVER put business logic in hooks
- Hooks use `useTRPC()` from `./trpc.ts`
- Both Next.js and TanStack Start apps use the same `<ApiProvider>`
## Usage in Apps
```tsx
import { ApiProvider, useTRPC } from "@repo/api-client";
// Root layout:
<ApiProvider trpcUrl="/api/trpc">{children}</ApiProvider>
// In components:
const trpc = useTRPC();
const articles = trpc.content.listArticles.useQuery({});
```
## Adding a New Hook (optional wrapper)
Custom hooks are optional — `useTRPC()` provides typed access to all procedures directly. Only create wrapper hooks if you need shared query logic across multiple components.

17
packages/api/AGENTS.md Normal file
View File

@@ -0,0 +1,17 @@
# @repo/api — tRPC Router Definitions
tRPC routers that call controllers from `@repo/core`. Each procedure validates input and delegates to a controller.
## Rules
- NEVER put business logic in routers — delegate to controllers
- Input validation uses Zod schemas
- Each domain gets its own router file
## Adding a New tRPC Router
1. Create `src/router/{domain}.router.ts`
2. Import `router` and `publicProcedure` from `../trpc.js`
3. Define procedures (`.query()` for reads, `.mutation()` for writes)
4. Each procedure calls a controller from `@repo/core`
5. Add router to root `appRouter` in `src/router/index.ts`

View File

@@ -0,0 +1,39 @@
# @repo/cms-client — Dual-Mode Payload Client
Provides typed access to Payload CMS via Local API (primary) or HTTP REST (fallback).
## THIS PACKAGE IS STANDALONE
- NEVER import from: `@repo/cms-core`, `@repo/core`, `apps/*`
- The Payload instance is INJECTED, not imported
- Types are generated via `payload generate:types`
## Initialization
| Context | Mode | How |
|---|---|---|
| apps/cms server | Local | `getPayload({config})` from @repo/cms-core |
| apps/web-next server | Local | `getPayload({config})` from @repo/cms-core |
| apps/web-tanstack server | Local | `getPayload({config})` from @repo/cms-core |
| Client-side (browser) | N/A | Goes through tRPC — server handles it |
| External services | HTTP | `createPayloadClient({mode:"http",baseURL})` |
```typescript
// In app startup (e.g., apps/web-next/src/lib/payload.ts):
import { getPayload } from "payload";
import { config } from "@repo/cms-core";
import { createPayloadClient } from "@repo/cms-client";
const payload = await getPayload({ config });
const client = createPayloadClient({ mode: "local", payload });
```
## Available Methods
All methods support full Payload query capabilities (where, sort, limit, depth, page, populate):
- `find(collection, options)` — paginated query
- `findByID(collection, id, options)` — single document
- `create(collection, data, options)` — create document
- `update(collection, id, data, options)` — update document
- `delete(collection, id)` — delete document

View File

@@ -0,0 +1,40 @@
# @repo/cms-core — Payload CMS Definition
All Payload configuration lives here: payload.config.ts, collections, globals, hooks, access control. The `apps/cms` app is a thin shell that imports this config.
## Hook Rules
| Category | Location | Examples |
|---|---|---|
| CMS-operational | Stay in hook | Slugify, image resize, default values |
| Business logic | Delegate to use case | Notifications, validation, cross-domain updates |
### DO
- Keep hooks thin (max 5-10 lines)
- Import use cases from `@repo/core/application`
- Map Payload hook args to use case input types
### DON'T
- Import from `@repo/core/infrastructure`
- Put business validation in hooks
- Call external services directly from hooks
- Duplicate logic that exists in a use case
## Adding a New Collection
1. Create folder: `src/collections/{name}/`
2. Create: `index.ts` (CollectionConfig), `fields.ts`
3. Optionally: `hooks/`, `access/`
4. Import in `src/payload.config.ts` collections array
5. Export from `src/index.ts`
## Adding a Hook That Calls a Use Case
1. Create `src/collections/{name}/hooks/{hook-name}.ts`
2. Import use case from `@repo/core` (application layer only)
3. Map Payload's hook args to use case input
4. Call use case, return data
**Rule of thumb:** If deleting the hook would break a business requirement, the logic must be in a use case.

59
packages/ui/AGENTS.md Normal file
View File

@@ -0,0 +1,59 @@
# @repo/ui — Atomic Design Component Library
shadcn/ui + Tailwind CSS v4 + Atomic Design. Components organized by level with co-located stories.
## Atomic Classification Guide
| Level | Definition | Examples |
|---|---|---|
| Atom | Single element, can't break down further | Button, Input, Label, Badge, Separator |
| Molecule | 2-3 atoms, single responsibility | FormField, SearchBar, Tooltip, Select |
| Organism | Complex section, self-contained | DataTable, Dialog, Header, Sidebar, Card |
| Template | Page layout, content-agnostic | DashboardLayout, AuthLayout |
| Page | Template + real data | **LIVES IN apps/, NOT HERE** |
## Import Rules
| Level | Can import from | NEVER import from |
|---|---|---|
| Atoms | lib/, hooks/, styles/ | molecules/, organisms/, templates/ |
| Molecules | atoms/, lib/, hooks/ | organisms/, templates/ |
| Organisms | atoms/, molecules/, lib/, hooks/ | templates/ |
| Templates | atoms/, molecules/, organisms/, lib/, hooks/ | (top level) |
## Component Rules
- **Atoms:** No margins/positioning, no state, no business logic
- **Molecules:** Single responsibility, minimal controlled state
- **Organisms:** Can have internal state and sub-components
- **Templates:** Use children/slots, NEVER hard-code content
- **All:** Co-locate `.stories.tsx` next to component
## shadcn/ui Workflow
1. `pnpm dlx shadcn@latest add [component]` — lands in atoms/ by default
2. Check classification guide above
3. If not atom → move to correct directory
4. Create `.stories.tsx` with title: `"{Level}/{ComponentName}"`
5. Update level's `index.ts` barrel
## Story Template
```tsx
import type { Meta, StoryObj } from "@storybook/react";
import { MyComponent } from "./my-component.js";
const meta = {
title: "{Level}/{ComponentName}",
component: MyComponent,
tags: ["autodocs"],
} satisfies Meta<typeof MyComponent>;
export default meta;
```
## Storybook MCP
Before creating UI components, query Storybook MCP:
- `list-all-documentation` — check for existing components
- `get-documentation` — understand props/variants
- After creating: `run-story-tests` to validate