IDE 配置与 Rules 记忆体系

AI 编程工具的效果 80% 取决于上下文质量。如果 AI 不知道你的技术栈、编码规范、项目结构,它生成的代码就像一个刚入职的实习生写的——语法正确但风格不对、结构混乱、缺少项目约定。Rules 文件(.cursorrules、CLAUDE.md、Windsurf Rules)就是你给 AI 的"入职手册",让它从第一行代码就像团队老成员一样工作。本章构建一套完整的分层规则体系。

1. 为什么 Rules 至关重要

1.1 没有 Rules 的问题

不配置 Rules 时,AI 工具会按照"通用最佳实践"生成代码。这在小 demo 中没问题,但在真实项目中会出现大量摩擦:

问题 1:技术栈不匹配
你用 Drizzle ORM,AI 生成 Prisma 代码
你用 App Router,AI 生成 Pages Router 代码
你用 Server Actions,AI 生成 API Routes

问题 2:编码风格不一致
你的项目用 single quotes,AI 生成 double quotes
你的错误处理用自定义 AppError,AI 用 throw new Error
你的组件放在 components/ui/,AI 创建在 src/components/

问题 3:安全约定遗漏
你的查询必须包含 tenantId,AI 忘了加
你的 Server Actions 必须检查权限,AI 跳过了
你的敏感数据不能出现在客户端,AI 把它放在了 props 里

每次手动修正这些问题,就是在浪费 AI 本该帮你节省的时间。好的 Rules 文件一次编写,持续受益

1.2 Rules 的本质

Rules 文件本质上是注入到 LLM System Prompt 中的项目上下文。AI 工具在每次对话开始时会自动读取这些文件,将其内容拼接到系统提示词中。

┌──────────────────────────────────────┐
│ System Prompt                        │
│  ├─ 工具内置的基础指令               │
│  ├─ 全局 Rules(用户级)              │
│  ├─ 项目 Rules(.cursorrules 等)     │
│  └─ 当前文件 / @引用的上下文          │
│                                      │
│ User Message                         │
│  └─ 你的提示词                        │
└──────────────────────────────────────┘

Rules 的字数直接消耗上下文窗口。写得太短 AI 不够了解项目,写得太长又挤压了代码空间。经验法则:控制在 500-2000 字之间

2. .cursorrules 深度配置

2.1 文件位置与生效范围

Cursor 支持多级 Rules:

文件位置范围优先级
全局 RulesCursor Settings → General → Rules for AI所有项目
项目 Rules项目根目录 .cursorrules当前项目
目录 Rules.cursor/rules/*.mdc匹配的文件

目录 Rules 是 Cursor 的高级特性——可以为不同目录/文件类型设置不同规则:

<!-- .cursor/rules/api-routes.mdc -->
---
globs: app/api/**/*.ts
---
# API Route Rules
- Always validate request body with zod
- Return proper HTTP status codes (400, 401, 403, 404, 500)
- Include rate limiting headers
- Log errors to Sentry
<!-- .cursor/rules/server-actions.mdc -->
---
globs: lib/actions/**/*.ts
---
# Server Action Rules
- Every action must start with requirePermission() check
- Use 'use server' directive at the top
- Validate all inputs with zod
- Revalidate affected paths after mutations
- Return typed results, not throw errors
<!-- .cursor/rules/components.mdc -->
---
globs: components/**/*.tsx
---
# Component Rules
- Use Server Components by default
- Add 'use client' only when using hooks, event handlers, or browser APIs
- Import UI primitives from @/components/ui/
- Use cn() for conditional classNames
- Props interface must be exported

2.2 Next.js 全栈项目 .cursorrules 模板

<!-- .cursorrules -->
# Project: NextSaaS Platform
 
## Tech Stack
- Next.js 15 with App Router (NOT Pages Router)
- TypeScript in strict mode
- Drizzle ORM with PostgreSQL (NOT Prisma, NOT raw SQL)
- Tailwind CSS v4 + shadcn/ui components
- Clerk for authentication
- Stripe for billing
- Inngest for background jobs
- Upstash Redis for caching and rate limiting
- Vercel for deployment
 
## Architecture
- app/(dashboard)/ - Authenticated routes with sidebar layout
- app/(marketing)/ - Public marketing pages
- app/(admin)/admin/ - Super admin panel
- app/api/ - REST APIs and webhooks only
- lib/actions/ - All mutations via Server Actions
- lib/db/schema.ts - Single source of truth for database schema
- lib/ai/ - AI feature modules
- components/ui/ - shadcn primitives (do not modify)
- components/ - App-level components
 
## Code Conventions
- Server Components by default; 'use client' only when required
- Server Actions for mutations; API routes only for webhooks and external APIs
- All DB queries must include tenantId (multi-tenant isolation)
- Use zod for validation everywhere (forms, API inputs, env vars)
- Error handling: return { error: string } from actions, never throw
- Use nanoid() for short IDs, uuid for database primary keys
- Prefer const arrow functions: const fn = () => {}
- Use path aliases: @/lib/, @/components/, @/app/
 
## Auth & Security
- requirePermission('resource:action') at the start of every Server Action
- Never expose sensitive data in Client Components
- Environment variables: validated with zod at startup
- API routes: validate auth token from headers
 
## Testing
- Vitest for unit tests
- Playwright for E2E tests
- Test files: __tests__/*.test.ts
- Mock database with drizzle-mock
 
## Common Patterns
- Pagination: use cursor-based pagination with startAfter
- Forms: React Hook Form + zod resolver + Server Action
- Optimistic updates: useOptimistic() hook
- Loading states: Suspense boundaries with skeleton fallbacks

3. CLAUDE.md 深度配置

3.1 CLAUDE.md 与 .cursorrules 的区别

维度.cursorrulesCLAUDE.md
工具CursorClaude Code
交互模式IDE 内对话终端自主执行
侧重点代码生成风格项目架构 + 命令 + 工作流
详细度精炼(节省上下文)可以更详细(Claude Code 窗口更大)
命令不需要必须包含常用命令

CLAUDE.md 需要包含更多"操作性"信息——因为 Claude Code 会自己执行命令,它需要知道怎么运行项目、怎么跑测试、怎么部署。

3.2 CLAUDE.md 分层结构

Claude Code 支持多级 CLAUDE.md:

项目根目录/
  CLAUDE.md          ← 全项目规则(必须)
  apps/
    web/
      CLAUDE.md      ← Web 应用特定规则
    api/
      CLAUDE.md      ← API 服务特定规则
  packages/
    db/
      CLAUDE.md      ← 数据库包规则

子目录的 CLAUDE.md 会叠加到父目录上,形成完整的上下文。

3.3 CLAUDE.md 模板

# NextSaaS Platform
 
## Quick Start
```bash
pnpm install          # Install dependencies
pnpm dev              # Start dev server at localhost:3000
pnpm db:generate      # Generate Drizzle migrations
pnpm db:push          # Push schema to database
pnpm db:studio        # Open Drizzle Studio
pnpm test             # Run Vitest tests
pnpm test:e2e         # Run Playwright E2E tests
pnpm lint             # ESLint + TypeScript check
pnpm build            # Production build

Architecture

  • Monorepo managed by Turborepo
  • Frontend: Next.js 15, App Router, React 19
  • Database: PostgreSQL on Neon, managed by Drizzle ORM
  • Auth: Clerk (multi-tenant, RBAC)
  • Payments: Stripe (subscriptions + usage-based)
  • Background Jobs: Inngest
  • Cache: Upstash Redis
  • AI: Vercel AI SDK + OpenAI/Anthropic
  • Deploy: Vercel

Key Directories

  • app/(dashboard)/ — authenticated user-facing routes
  • app/(admin)/admin/ — super admin panel (email whitelist)
  • lib/actions/ — Server Actions (every action starts with requirePermission)
  • lib/db/schema.ts — single source of truth for all tables
  • lib/ai/ — AI features (chat, RAG, agent, tools)
  • components/ui/ — shadcn/ui primitives (never modify these)

Coding Standards

  • TypeScript strict mode, no any unless justified with comment
  • Server Components by default; 'use client' only for interactivity
  • All DB queries MUST include tenantId — multi-tenant isolation is mandatory
  • Input validation: zod everywhere (Server Actions, API routes, env vars)
  • Errors: return { error: string } from actions, never throw
  • Naming: camelCase for variables/functions, PascalCase for components/types
  • Imports: use @/ path alias, never relative paths crossing directories

Testing

  • Unit tests: pnpm test (Vitest)
  • E2E tests: pnpm test:e2e (Playwright)
  • Test co-located: __tests__/ next to source files
  • Before committing: run pnpm lint && pnpm test

Git Conventions

  • Branch: feat/xxx, fix/xxx, chore/xxx
  • Commit: conventional commits (feat:, fix:, chore:, docs:)
  • Always create a branch, never commit directly to main
  • PR description should reference the task or issue

Environment Variables

  • Copy .env.example to .env.local for local development
  • Required: DATABASE_URL, CLERK_SECRET_KEY, STRIPE_SECRET_KEY
  • AI features: OPENAI_API_KEY, ANTHROPIC_API_KEY
  • Never commit .env.local

Common Gotchas

  • Clerk middleware in middleware.ts must be updated when adding new public routes
  • Stripe webhook endpoint needs raw body — do not use Next.js body parser
  • Drizzle migrations: always review generated SQL before pushing
  • Server Actions cannot return non-serializable values (no Date, Map, Set)

## 4. Windsurf Rules 配置

### 4.1 Windsurf 的 Rules 体系

Windsurf 有两种 Rules 方式:

**全局 Rules**:Settings → Cascade → Global Rules

**项目 Rules**:`.windsurf/rules/*.md` 文件,支持 frontmatter 配置触发条件:

```markdown
<!-- .windsurf/rules/nextjs-conventions.md -->
---
trigger: always
---
# Next.js Conventions
- Use App Router with Server Components
- Server Actions for mutations
- Drizzle ORM for database queries
<!-- .windsurf/rules/testing.md -->
---
trigger: glob
globs: **/*.test.ts, **/*.spec.ts
---
# Testing Rules
- Use Vitest with describe/it pattern
- Mock external services, never call real APIs in tests
- Test both success and error paths

4.2 Windsurf Memory 系统

Windsurf 独有 Memory 功能——AI 自动或手动记住跨会话的上下文:

// 自动记忆:Cascade 在会话中发现的重要信息
"这个项目使用 Clerk webhook 而不是 middleware 来同步用户"

// 手动记忆:你告诉 Cascade 记住的信息
"记住:部署前必须先运行 pnpm db:push"

Memories 存储在 .windsurf/ 目录中,可以查看和管理。

5. 分层规则体系设计

5.1 三层规则架构

┌─────────────────────────────────────┐
│ Layer 1: 全局规则(跨项目)          │
│   通用编码风格、安全规范、AI 行为    │
├─────────────────────────────────────┤
│ Layer 2: 项目规则(项目级)          │
│   技术栈、架构、命令、约定          │
├─────────────────────────────────────┤
│ Layer 3: 模块规则(目录/文件级)     │
│   API 路由规范、组件规范、测试规范   │
└─────────────────────────────────────┘

Layer 1 示例:全局 Rules

# Global AI Rules
 
## Behavior
- Think step by step before writing code
- Ask for clarification if the task is ambiguous
- Prefer editing existing code over creating new files
- Never delete tests or weaken assertions
- Always preserve existing comments
 
## Security
- Never hardcode secrets, API keys, or passwords
- Never expose server-only data in client components
- Validate all external inputs
- Use parameterized queries, never string concatenation for SQL

Layer 2 示例:项目 Rules

# Project Rules
(内容同 2.2 节和 3.3 节的模板)

Layer 3 示例:模块 Rules

<!-- .cursor/rules/database.mdc -->
---
globs: lib/db/**/*.ts
---
# Database Module Rules
- Schema changes: add fields as nullable first, then backfill, then add NOT NULL
- All tables must have: id, tenantId, createdAt, updatedAt
- Use Drizzle's .returning() for INSERT/UPDATE
- Index all foreign keys and frequently queried columns
- Soft delete: add deletedAt column instead of DELETE

5.2 规则维护工作流

Rules 不是写一次就不管了——随着项目发展需要持续更新:

1. 项目初始化时
   → 从模板创建 .cursorrules / CLAUDE.md
   → 根据实际技术栈调整

2. 引入新技术时
   → 更新 Tech Stack 部分
   → 添加相关编码规范

3. 发现 AI 犯重复错误时
   → 将修正规则加入 Rules
   → 例:AI 总是忘记加 tenantId → 加粗强调

4. Code Review 发现模式问题时
   → 将模式固化为 Rules
   → 例:团队决定统一错误处理方式 → 写入规范

5. 定期审查(每月)
   → 删除过时规则
   → 合并重复规则
   → 优化措辞(更简洁 = 更少 token 消耗)

6. 跨工具 Rules 统一

6.1 统一模板生成脚本

如果团队同时使用多个 AI 工具,维护多份 Rules 很痛苦。可以用一个源文件生成所有格式:

// scripts/generate-rules.ts
import fs from 'fs'
import path from 'path'
 
// 单一数据源
const PROJECT_RULES = {
  name: 'NextSaaS',
  stack: {
    framework: 'Next.js 15 (App Router)',
    language: 'TypeScript (strict)',
    orm: 'Drizzle ORM + PostgreSQL',
    styling: 'Tailwind CSS v4 + shadcn/ui',
    auth: 'Clerk',
    payments: 'Stripe',
  },
  conventions: [
    'Server Components by default',
    'Server Actions for mutations',
    'All DB queries must include tenantId',
    'zod for all input validation',
    'requirePermission() at start of every Server Action',
  ],
  commands: {
    dev: 'pnpm dev',
    test: 'pnpm test',
    build: 'pnpm build',
    dbGenerate: 'pnpm db:generate',
    dbPush: 'pnpm db:push',
  },
}
 
// 生成 .cursorrules
function generateCursorRules(): string {
  return `# ${PROJECT_RULES.name}
 
## Tech Stack
${Object.entries(PROJECT_RULES.stack).map(([k, v]) => `- ${v}`).join('\n')}
 
## Code Conventions
${PROJECT_RULES.conventions.map(c => `- ${c}`).join('\n')}
`
}
 
// 生成 CLAUDE.md
function generateClaudeMd(): string {
  return `# ${PROJECT_RULES.name}
 
## Commands
${Object.entries(PROJECT_RULES.commands).map(([k, v]) => `- \`${v}\``).join('\n')}
 
## Tech Stack
${Object.entries(PROJECT_RULES.stack).map(([k, v]) => `- ${v}`).join('\n')}
 
## Conventions
${PROJECT_RULES.conventions.map(c => `- ${c}`).join('\n')}
`
}
 
fs.writeFileSync('.cursorrules', generateCursorRules())
fs.writeFileSync('CLAUDE.md', generateClaudeMd())
console.log('Rules generated for all tools.')

本章小结

  • Rules 是 AI 编程的基础设施:没有 Rules,AI 生成的代码与你的项目风格不匹配
  • 三层架构:全局规则(跨项目)→ 项目规则(技术栈/架构)→ 模块规则(目录/文件级)
  • .cursorrules:Cursor 的项目规则,侧重代码生成风格和结构
  • .cursor/rules/*.mdc:Cursor 的目录级规则,用 glob 匹配文件范围
  • CLAUDE.md:Claude Code 的项目记忆,必须包含命令、架构、约定
  • Windsurf Rules:支持 trigger 条件,加 Memory 跨会话记忆
  • 持续维护:Rules 不是一次性的,每次发现 AI 犯重复错误就更新
  • 统一管理:多工具环境用脚本从单一源生成各格式 Rules