diff --git a/AGENTS.md b/AGENTS.md index 1f401b7..c8365a1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,7 @@ This document provides comprehensive guidelines for AI coding agents working in - **Database**: PostgreSQL with Drizzle ORM - **State Management**: TanStack Query - **Routing**: TanStack Router (file-based) +- **RPC**: ORPC (type-safe RPC with contract-first design) - **Build Tool**: Vite - **Linter/Formatter**: Biome @@ -212,9 +213,19 @@ src/ │ ├── schema/ # Drizzle schema definitions │ └── index.ts # Database instance ├── lib/ # Utility functions +├── orpc/ # ORPC (RPC layer) +│ ├── contracts/ # Contract definitions (input/output schemas) +│ ├── handlers/ # Server-side procedure implementations +│ ├── middlewares/ # Middleware (e.g., DB provider) +│ ├── contract.ts # Contract aggregation +│ ├── router.ts # Router composition +│ ├── server.ts # Server instance +│ ├── client.ts # Isomorphic client +│ └── types.ts # Type utilities ├── routes/ # TanStack Router file-based routes │ ├── __root.tsx # Root layout -│ └── index.tsx # Home page +│ ├── index.tsx # Home page +│ └── api/rpc.$.ts # ORPC HTTP endpoint ├── env.ts # Environment variable validation ├── index.ts # Application entry point ├── router.tsx # Router configuration @@ -261,7 +272,52 @@ const myServerFn = createServerFn({ method: 'POST' }) }) ``` +### Creating ORPC Procedures + +**Step 1: Define Contract** (`src/orpc/contracts/my-feature.ts`) +```typescript +import { oc } from '@orpc/contract' +import { z } from 'zod' + +export const myContract = { + get: oc.input(z.object({ id: z.uuid() })).output(mySchema), + create: oc.input(createSchema).output(mySchema), +} +``` + +**Step 2: Implement Handler** (`src/orpc/handlers/my-feature.ts`) +```typescript +import { os } from '@/orpc/server' +import { dbProvider } from '@/orpc/middlewares' + +export const get = os.myFeature.get + .use(dbProvider) + .handler(async ({ context, input }) => { + const item = await context.db.query.myTable.findFirst(...) + return item + }) +``` + +**Step 3: Register in Contract & Router** +```typescript +// src/orpc/contract.ts +export const contract = { + myFeature: myContract, +} + +// src/orpc/router.ts +import * as myFeature from './handlers/my-feature' +export const router = os.router({ myFeature }) +``` + +**Step 4: Use in Component** +```typescript +import { orpc } from '@/orpc' +const query = useSuspenseQuery(orpc.myFeature.get.queryOptions({ id })) +const mutation = useMutation(orpc.myFeature.create.mutationOptions()) +``` + --- -**Last Updated**: 2026-01-17 +**Last Updated**: 2026-01-18 **Project Version**: Based on package.json dependencies