# Documentation And Adrs

> 记录决策与文档。适用于做架构决策、修改公开 API、发布功能，或需要为未来的工程师与 agent 留下理解代码库所需背景时。

- Skill: `233i/documentation-and-adrs` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 233i/documentation-and-adrs`
- Raw SKILL.md: https://api.skillmd.com/api/skills/233i/documentation-and-adrs/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: 233i (https://skillmd.com/u/233i)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/233i/documentation-and-adrs

---


# 文档与 ADR

## 概览

记录的不只是代码，更要记录决策。最有价值的文档，保存的是 *why*，也就是做出这个决定时的背景、约束和权衡。代码展示了 *what* 被构建出来，文档解释了 *why it was built this way*，以及 *what alternatives were considered*。这些背景信息，对未来继续维护代码库的人类和 agent 都至关重要。

## 何时使用

- 做重要的架构决策
- 在多个方案之间做选择
- 新增或修改公开 API
- 发布会改变用户可见行为的功能
- 帮助新成员或新 agent 理解项目
- 当你发现自己在重复解释同一件事时

**不适用的场景：** 不要为显而易见的代码写文档；不要写只是复述代码内容的注释；也不要给一次性原型写厚重文档。

## 架构决策记录（ADR）

ADR 用于记录重要技术决策背后的推理过程。它们是你能写出的最高价值文档之一。

### 什么时候该写 ADR

- 选择框架、库或关键依赖
- 设计数据模型或数据库 schema
- 确定认证策略
- 决定 API 架构，例如 REST、GraphQL 或 tRPC
- 在构建工具、托管平台或基础设施之间做选择
- 任何将来回滚代价很高的决策

### ADR 模板

将 ADR 按顺序编号，存放在 `docs/decisions/` 中：

```markdown
# ADR-001: Use PostgreSQL for primary database

## Status
Accepted | Superseded by ADR-XXX | Deprecated

## Date
2025-01-15

## Context
We need a primary database for the task management application. Key requirements:
- Relational data model (users, tasks, teams with relationships)
- ACID transactions for task state changes
- Support for full-text search on task content
- Managed hosting available (for small team, limited ops capacity)

## Decision
Use PostgreSQL with Prisma ORM.

## Alternatives Considered

### MongoDB
- Pros: Flexible schema, easy to start with
- Cons: Our data is inherently relational; would need to manage relationships manually
- Rejected: Relational data in a document store leads to complex joins or data duplication

### SQLite
- Pros: Zero configuration, embedded, fast for reads
- Cons: Limited concurrent write support, no managed hosting for production
- Rejected: Not suitable for multi-user web application in production

### MySQL
- Pros: Mature, widely supported
- Cons: PostgreSQL has better JSON support, full-text search, and ecosystem tooling
- Rejected: PostgreSQL is the better fit for our feature requirements

## Consequences
- Prisma provides type-safe database access and migration management
- We can use PostgreSQL's full-text search instead of adding Elasticsearch
- Team needs PostgreSQL knowledge (standard skill, low risk)
- Hosting on managed service (Supabase, Neon, or RDS)
```

### ADR 生命周期

```
PROPOSED → ACCEPTED → (SUPERSEDED or DEPRECATED)
```

- **不要删除旧 ADR。** 它们保存了历史上下文。
- 如果决策发生变化，写新的 ADR，并引用与替代旧 ADR。

## 内联文档

### 什么时候该写注释

注释要解释 *why*，而不是 *what*：

```typescript
// BAD: Restates the code
// Increment counter by 1
counter += 1;

// GOOD: Explains non-obvious intent
// Rate limit uses a sliding window — reset counter at window boundary,
// not on a fixed schedule, to prevent burst attacks at window edges
if (now - windowStart > WINDOW_SIZE_MS) {
  counter = 0;
  windowStart = now;
}
```

### 什么时候不要写注释

```typescript
// 不要给一看就懂的代码加注释
function calculateTotal(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}

// 不要留下其实现在就该做掉的 TODO
// TODO: add error handling  ← 直接补上

// 不要保留被注释掉的旧代码
// const oldImplementation = () => { ... }  ← 删掉，git 有历史
```

### 记录已知陷阱

```typescript
/**
 * IMPORTANT: This function must be called before the first render.
 * If called after hydration, it causes a flash of unstyled content
 * because the theme context isn't available during SSR.
 *
 * See ADR-003 for the full design rationale.
 */
export function initializeTheme(theme: Theme): void {
  // ...
}
```

## API 文档

对于公开 API，例如 REST、GraphQL 或库接口：

### 和类型写在一起（TypeScript 首选）

```typescript
/**
 * Creates a new task.
 *
 * @param input - Task creation data (title required, description optional)
 * @returns The created task with server-generated ID and timestamps
 * @throws {ValidationError} If title is empty or exceeds 200 characters
 * @throws {AuthenticationError} If the user is not authenticated
 *
 * @example
 * const task = await createTask({ title: 'Buy groceries' });
 * console.log(task.id); // "task_abc123"
 */
export async function createTask(input: CreateTaskInput): Promise<Task> {
  // ...
}
```

### REST API 用 OpenAPI / Swagger

```yaml
paths:
  /api/tasks:
    post:
      summary: Create a task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTaskInput'
      responses:
        '201':
          description: Task created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '422':
          description: Validation error
```

## README 结构

每个项目都应该有一个 README，至少覆盖：

```markdown
# Project Name

One-paragraph description of what this project does.

## Quick Start
1. Clone the repo
2. Install dependencies: `npm install`
3. Set up environment: `cp .env.example .env`
4. Run the dev server: `npm run dev`

## Commands
| Command | Description |
|---------|-------------|
| `npm run dev` | Start development server |
| `npm test` | Run tests |
| `npm run build` | Production build |
| `npm run lint` | Run linter |

## Architecture
Brief overview of the project structure and key design decisions.
Link to ADRs for details.

## Contributing
How to contribute, coding standards, PR process.
```

## Changelog 维护

对于已经发布的功能：

```markdown
# Changelog

## [1.2.0] - 2025-01-20
### Added
- Task sharing: users can share tasks with team members (#123)
- Email notifications for task assignments (#124)

### Fixed
- Duplicate tasks appearing when rapidly clicking create button (#125)

### Changed
- Task list now loads 50 items per page (was 20) for better UX (#126)
```

## 面向 Agent 的文档

对 AI agent 还要额外考虑以下文档：

- **CLAUDE.md / rules files**：记录项目约定，让 agent 按你的方式工作
- **Spec files**：保持 spec 最新，让 agent 构建正确的东西
- **ADRs**：帮助 agent 理解决策背景，避免它重复讨论旧结论
- **Inline gotchas**：防止 agent 掉进已知坑里

## 常见自我安慰

| 自我安慰 | 现实 |
|---|---|
| “代码本身就是文档” | 代码只能说明做了什么，不能说明为什么做、拒绝了什么方案、受哪些约束限制。 |
| “等 API 稳定了再写文档” | API 往往会因为文档而更快稳定下来。文档本身就是设计的第一轮测试。 |
| “没人看文档” | Agent 会看。未来的工程师会看。三个月后的你自己也会看。 |
| “ADR 是额外负担” | 一份 10 分钟的 ADR，能省掉 6 个月后一次 2 小时的重复争论。 |
| “注释会过时” | 写 why 类型注释通常很稳定；写 what 类型注释才容易过时，所以只写前者。 |

## 危险信号

- 架构决策没有任何书面理由
- 公开 API 没有文档或类型说明
- README 没解释项目怎么跑起来
- 用注释掉的旧代码代替删除
- TODO 注释挂了几周都没处理
- 一个有明显架构选择的项目却没有 ADR
- 文档只是复述代码，而不是解释意图

## 验证

写完文档后，确认：

- [ ] 所有重要架构决策都有 ADR
- [ ] README 覆盖 quick start、commands 和 architecture overview
- [ ] API 函数有参数与返回值说明
- [ ] 重要 gotcha 已在真正相关的位置用内联文档记录
- [ ] 没有残留被注释掉的旧代码
- [ ] 规则文件（CLAUDE.md 等）内容是最新且准确的

