feat: add AGENTS.md for all packages and apps (9 files)
This commit is contained in:
27
packages/api-client/AGENTS.md
Normal file
27
packages/api-client/AGENTS.md
Normal 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
17
packages/api/AGENTS.md
Normal 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`
|
||||
39
packages/cms-client/AGENTS.md
Normal file
39
packages/cms-client/AGENTS.md
Normal 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
|
||||
40
packages/cms-core/AGENTS.md
Normal file
40
packages/cms-core/AGENTS.md
Normal 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
59
packages/ui/AGENTS.md
Normal 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
|
||||
Reference in New Issue
Block a user