From fd9478d64e76f20c1eb57ddcebc5a5729c4b4b90 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Thu, 5 Mar 2026 10:21:31 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=90=8C=E6=AD=A5=20AGENTS.md=20?= =?UTF-8?q?=E8=87=B3=20Drizzle=20v1=20beta=20=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=8E=9F=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 所有 AGENTS.md 新增「开发原则」:不向后兼容、改代码必须同步文档、前向迁移 - 根 AGENTS.md: 更新 Database 段落为 Drizzle v1 beta + postgres-js + RQBv2 - server AGENTS.md: 更新 tech stack、目录结构、ORPC 示例、数据库段落 - drizzle-zod → drizzle-orm/zod - bun-sql → postgres-js - RQBv1 回调 → RQBv2 对象语法 - 新增 relations.ts 和 DB instance 示例 - desktop AGENTS.md: 添加开发原则和文档同步规则 --- AGENTS.md | 18 ++++++++++- apps/desktop/AGENTS.md | 9 ++++++ apps/server/AGENTS.md | 72 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b9334fa..7f92207 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -120,7 +120,13 @@ import type { ReactNode } from 'react' - ORPC: Use `ORPCError` with proper codes (`NOT_FOUND`, `INPUT_VALIDATION_FAILED`) - Never use empty catch blocks -## Database (Drizzle ORM) +## Database (Drizzle ORM v1 beta + postgres-js) + +- **ORM**: Drizzle ORM `1.0.0-beta` (RQBv2) +- **Driver**: `drizzle-orm/postgres-js` (NOT `bun-sql`) +- **Validation**: `drizzle-orm/zod` (built-in, NOT separate `drizzle-zod` package) +- **Relations**: Defined via `defineRelations()` in `src/server/db/relations.ts` +- **Query style**: RQBv2 object syntax (`orderBy: { createdAt: 'desc' }`, `where: { id: 1 }`) ```typescript export const myTable = pgTable('my_table', { @@ -143,6 +149,14 @@ export const myTable = pgTable('my_table', { - Workspace packages use `"catalog:"` — never hardcode versions - Internal packages use `"workspace:*"` references +## Development Principles + +> **These principles apply to ALL code changes. Agents MUST follow them on every task.** + +1. **No backward compatibility** — This project is in rapid iteration. Always use the latest API and patterns. Never keep deprecated code paths or old API fallbacks "just in case". +2. **Always sync documentation** — When code changes, immediately update all related documentation (`AGENTS.md`, `README.md`, inline code examples). Code and docs must never drift apart. This includes updating code snippets in docs when imports, APIs, or patterns change. +3. **Forward-only migration** — When upgrading dependencies, fully adopt the new API. Don't mix old and new patterns in the same codebase. + ## Critical Rules **DO:** @@ -150,6 +164,7 @@ export const myTable = pgTable('my_table', { - Use `@/*` path aliases (not relative imports) - Include `createdAt`/`updatedAt` on all tables - Use `catalog:` for dependency versions +- Update `AGENTS.md` and other docs whenever code patterns change **DON'T:** - Use `npm`, `npx`, `node`, `yarn`, `pnpm` — always use `bun` / `bunx` @@ -158,6 +173,7 @@ export const myTable = pgTable('my_table', { - Commit `.env` files - Use empty catch blocks `catch(e) {}` - Hardcode dependency versions in workspace packages +- Leave docs out of sync with code changes ## Git Workflow diff --git a/apps/desktop/AGENTS.md b/apps/desktop/AGENTS.md index 0b39d90..1384aa7 100644 --- a/apps/desktop/AGENTS.md +++ b/apps/desktop/AGENTS.md @@ -73,6 +73,14 @@ The `electron-builder.yml` `extraResources` config reads binaries directly from To build for a specific platform explicitly, use `bun dist:linux` / `bun dist:mac` / `bun dist:win` in `apps/desktop`. For single-arch output, use `bun dist:linux:x64`, `bun dist:linux:arm64`, `bun dist:mac:x64`, or `bun dist:mac:arm64`. +## Development Principles + +> **These principles apply to ALL code changes. Agents MUST follow them on every task.** + +1. **No backward compatibility** — This project is in rapid iteration. Always use the latest API and patterns. Never keep deprecated code paths or old API fallbacks. +2. **Always sync documentation** — When code changes, immediately update all related documentation (`AGENTS.md`, `README.md`, inline code examples). Code and docs must never drift apart. +3. **Forward-only migration** — When upgrading dependencies, fully adopt the new API. Don't mix old and new patterns. + ## Critical Rules **DO:** @@ -84,3 +92,4 @@ For single-arch output, use `bun dist:linux:x64`, `bun dist:linux:arm64`, `bun d - Use `npm`, `npx`, `yarn`, or `pnpm`. Use `bun` for package management. - Include UI components or business logic in the desktop app. - Use `as any` or `@ts-ignore`. +- Leave docs out of sync with code changes. diff --git a/apps/server/AGENTS.md b/apps/server/AGENTS.md index 6f14096..e56eb6f 100644 --- a/apps/server/AGENTS.md +++ b/apps/server/AGENTS.md @@ -11,7 +11,7 @@ TanStack Start fullstack web app with ORPC (contract-first RPC). - **Package Manager**: Bun — **NOT npm / yarn / pnpm** - **Language**: TypeScript (strict mode) - **Styling**: Tailwind CSS v4 -- **Database**: PostgreSQL + Drizzle ORM +- **Database**: PostgreSQL + Drizzle ORM v1 beta (`drizzle-orm/postgres-js`, RQBv2) - **State**: TanStack Query v5 - **RPC**: ORPC (contract-first, type-safe) - **Build**: Vite + Nitro @@ -72,7 +72,8 @@ src/ │ │ └── types.ts # Type exports │ └── db/ │ ├── schema/ # Drizzle table definitions -│ └── index.ts # Database instance +│ ├── relations.ts # Drizzle relations (defineRelations, RQBv2) +│ └── index.ts # Database instance (postgres-js driver) ├── env.ts # Environment variable validation ├── router.tsx # Router configuration ├── routeTree.gen.ts # Auto-generated (DO NOT EDIT) @@ -84,7 +85,7 @@ src/ ### 1. Define Contract (`src/server/api/contracts/feature.contract.ts`) ```typescript import { oc } from '@orpc/contract' -import { createSelectSchema } from 'drizzle-zod' +import { createSelectSchema } from 'drizzle-orm/zod' import { z } from 'zod' import { featureTable } from '@/server/db/schema' @@ -101,7 +102,9 @@ import { db } from '../middlewares' import { os } from '../server' export const list = os.feature.list.use(db).handler(async ({ context }) => { - return await context.db.query.featureTable.findMany() + return await context.db.query.featureTable.findMany({ + orderBy: { createdAt: 'desc' }, + }) }) ``` @@ -125,8 +128,14 @@ const { data } = useSuspenseQuery(orpc.feature.list.queryOptions()) const mutation = useMutation(orpc.feature.create.mutationOptions()) ``` -## Database Schema (Drizzle) +## Database (Drizzle ORM v1 beta) +- **Driver**: `drizzle-orm/postgres-js` (NOT `bun-sql`) +- **Validation**: `drizzle-orm/zod` (built-in, NOT separate `drizzle-zod` package) +- **Relations**: Defined via `defineRelations()` in `src/server/db/relations.ts` +- **Query**: RQBv2 — use `db.query.tableName.findMany()` with object-style `orderBy` and `where` + +### Schema Definition ```typescript import { pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core' import { sql } from 'drizzle-orm' @@ -139,6 +148,44 @@ export const myTable = pgTable('my_table', { }) ``` +### Relations (RQBv2) +```typescript +// src/server/db/relations.ts +import { defineRelations } from 'drizzle-orm' +import * as schema from './schema' + +export const relations = defineRelations(schema, (r) => ({ + // Define relations here using r.one / r.many / r.through +})) +``` + +### DB Instance +```typescript +// src/server/db/index.ts +import { drizzle } from 'drizzle-orm/postgres-js' +import { relations } from '@/server/db/relations' +import * as schema from '@/server/db/schema' + +const db = drizzle({ + connection: env.DATABASE_URL, + schema, + relations, +}) +``` + +### RQBv2 Query Examples +```typescript +// Object-style orderBy (NOT callback style) +const todos = await db.query.todoTable.findMany({ + orderBy: { createdAt: 'desc' }, +}) + +// Object-style where +const todo = await db.query.todoTable.findFirst({ + where: { id: someId }, +}) +``` + ## Code Style ### Formatting (Biome) @@ -197,6 +244,14 @@ export const env = createEnv({ }) ``` +## Development Principles + +> **These principles apply to ALL code changes. Agents MUST follow them on every task.** + +1. **No backward compatibility** — This project is in rapid iteration. Always use the latest API and patterns. Never keep deprecated code paths or old API fallbacks. +2. **Always sync documentation** — When code changes, immediately update all related documentation (`AGENTS.md`, `README.md`, inline code examples). Code and docs must never drift apart. +3. **Forward-only migration** — When upgrading dependencies, fully adopt the new API. Don't mix old and new patterns. + ## Critical Rules **DO:** @@ -204,6 +259,9 @@ export const env = createEnv({ - Use `@/*` path aliases - Include `createdAt`/`updatedAt` on all tables - Use `ORPCError` with proper codes +- Use `drizzle-orm/zod` (NOT `drizzle-zod`) for schema validation +- Use RQBv2 object syntax for `orderBy` and `where` +- Update `AGENTS.md` and other docs whenever code patterns change **DON'T:** - Use `npm`, `npx`, `node`, `yarn`, `pnpm` — always use `bun` / `bunx` @@ -211,3 +269,7 @@ export const env = createEnv({ - Use `as any`, `@ts-ignore`, `@ts-expect-error` - Commit `.env` files - Use empty catch blocks +- Import from `drizzle-zod` (use `drizzle-orm/zod` instead) +- Use RQBv1 callback-style `orderBy` / old `relations()` API +- Use `drizzle-orm/bun-sql` driver (use `drizzle-orm/postgres-js`) +- Leave docs out of sync with code changes