<!-- title: Claude Code遗留系统迁移与重构全实战 -->

# Claude Code遗留系统迁移与重构全实战

> **学习目标**：掌握使用Claude Code安全、增量地迁移和重构遗留代码库的完整工作流——从代码考古、特征测试、依赖映射，到Strangler Fig模式的并行重构，最终实现"零停机"的渐进式现代化。
>
> **适用人群**：接手过"祖传代码"的后端/全栈开发者，有一定Claude Code使用经验，希望系统化地完成大规模代码迁移任务。

---

## 前置条件

| 条件 | 说明 |
|------|------|
| Claude Code CLI | 已安装并完成API认证（`claude` 命令可用） |
| Git ≥ 2.5 | 需要worktree功能进行并行开发 |
| 遗留代码库 | 任意语言的遗留项目（本文以Node.js/Express 4为例，方法通用） |
| 基础概念 | 了解单元测试、Git分支策略、CI/CD基本流程 |
| Context预算 | 建议使用Opus模型处理复杂重构决策 |

---

## 一、为什么AI改变了遗留代码的游戏规则

传统遗留迁移失败率极高——Gartner报告显示超过70%的现代化项目超期或失败。原因不是写新代码难，而是**理解旧代码难**。一个运行了5年的遗留系统里埋藏着：

- 数百个未文档化的产品决策
- 隐式的业务规则和边界条件
- "这里改了会炸"的脆弱耦合
- 十几位开发者各自的编码风格

Claude Code的200K+ token上下文窗口可以一次容纳整个中小型代码库的核心逻辑，这让**代码考古**（Code Archaeology）——系统性理解遗留代码的第一步——从数周缩短到数小时。

```mermaid
graph TD
    A[遗留代码库] --> B{迁移策略选择}
    B -->|大爆炸重写| C[高风险 高回报]
    B -->|Strangler Fig增量| D[低风险 持续交付]
    B -->|绞杀者+AI辅助| E[最优解: Claude Code]
    C --> F[失败率>70%]
    D --> G[安全渐进]
    E --> H[理解旧代码→特征测试→增量替换]
    H --> G
```

---

## 二、第一步：代码考古——让Claude Code读懂遗留代码

### 2.1 项目初始化与上下文建立

进入遗留项目目录后，第一步不是动手改代码，而是**建立上下文**：

```bash
cd legacy-project/
claude
```

在Claude Code会话中执行：

```
/init
```

`/init`命令会扫描项目结构，自动生成一个初始的`CLAUDE.md`文件。对于遗留项目，这个文件需要大幅定制。

### 2.2 定制CLAUDE.md——遗留项目的"认知蓝图"

手动编辑`CLAUDE.md`，补充AI无法自动推断的关键信息：

```markdown
# 项目概述

## 遗留系统概况
- 技术栈: Express 4 + MongoDB + EJS模板
- 起始年份: 2019
- 主要语言: JavaScript (ES5为主，部分ES6)
- 测试覆盖率: ~12% (仅集成测试)
- 最后一次框架升级: 2020年

## 架构说明
- 路由定义: routes/ 目录，每个文件对应一个资源
- 业务逻辑: 散落在路由回调中，无分层
- 数据访问: 直接在路由中调用MongoDB驱动
- 认证: 自定义session中间件，非Passport
- 配置: 硬编码在代码中 + .env混合

## 已知痛点
- callbacks地狱，无async/await
- 全局变量共享状态
- 无类型检查
- 错误处理不一致（部分throw，部分next(err)）
- 报表模块包含大量硬编码的客户专属逻辑

## 迁移目标
- [ ] Express 4 → Express 5 + TypeScript
- [ ] callbacks → async/await
- [ ] MongoDB驱动 → Mongoose ODM
- [ ] 测试覆盖率 → 70%+
- [ ] 引入分层架构（Controller/Service/Repository）

## 安全约束
- API接口签名不可变（有外部系统依赖）
- 报表模块最后迁移（业务逻辑最复杂）
- 每次迁移必须通过现有集成测试

## 构建与测试命令
- npm start (启动开发服务器)
- npm test (运行集成测试)
- npm run lint (ESLint检查)
```

### 2.3 让Claude Code绘制架构地图

在会话中请求Claude Code分析代码结构：

```
请分析这个项目的完整架构：
1. 列出所有路由及其对应的处理函数
2. 识别所有数据库集合及其使用模式
3. 找出所有中间件及其执行顺序
4. 标记出最复杂的10个文件（按耦合度排序）
5. 识别隐式依赖和循环引用
```

Claude Code会读取整个项目并生成一份详细的架构报告。保存这份报告：

```
请将上面的分析结果保存为 docs/architecture-map.md
```

### 2.4 依赖关系可视化

让Claude Code生成依赖图：

```
分析 routes/ 和 models/ 之间的所有依赖关系，
用Mermaid图表示出来，标注每个依赖的类型（数据访问、函数调用、共享状态）
```

```mermaid
graph LR
    subgraph "路由层"
        R1[routes/users.js]
        R2[routes/orders.js]
        R3[routes/reports.js]
        R4[routes/auth.js]
    end
    subgraph "数据层(无抽象)"
        DB[(MongoDB直接调用)]
        M1[models/user.js]
        M2[models/order.js]
    end
    subgraph "共享状态(风险)"
        G1[全局config对象]
        G2[全局cache对象]
    end

    R1 -->|直接查询| DB
    R1 -->|引用| M1
    R2 -->|直接查询| DB
    R2 -->|引用| M2
    R3 -->|直接查询| DB
    R3 -->|读取| G1
    R3 -->|读取| G2
    R4 -->|直接查询| DB
    R1 -.->|共享| G2
    R2 -.->|共享| G1

    style G1 fill:#ff6b6b,color:#fff
    style G2 fill:#ff6b6b,color:#fff
    style R3 fill:#ffd93d
```

**红色节点**代表高风险的全局共享状态，**黄色节点**是最复杂的模块（reports），这些信息决定了迁移的优先级。

---

## 三、第二步：构建安全网——特征测试（Characterization Tests）

在动任何代码之前，必须先**锁定当前行为**。特征测试不是断言"应该怎样"，而是记录"实际怎样"。

### 3.1 用Claude Code批量生成特征测试

```
请为 routes/users.js 中的每个路由处理函数生成特征测试。
要求：
1. 测试文件放在 test/characterization/ 目录
2. 使用 supertest + jest
3. 记录当前API的实际响应（状态码、响应体结构、响应时间）
4. 不做任何断言修改——只记录事实
5. 使用真实数据库的snapshot数据（test/fixtures/）
```

Claude Code会生成类似这样的测试：

```javascript
// test/characterization/users.test.js
const request = require('supertest');
const app = require('../../app');

describe('GET /api/users - 特征测试 (勿修改)', () => {
  test('返回200和用户列表数组', async () => {
    const response = await request(app)
      .get('/api/users')
      .set('Authorization', 'Bearer test-token-admin');

    // 特征记录：实际行为快照
    expect(response.status).toBe(200);
    expect(response.body).toHaveProperty('users');
    expect(Array.isArray(response.body.users)).toBe(true);
    // 注意：分页参数返回为字符串而非数字（已知遗留问题）
    expect(response.body.page).toBe('1'); // 字符串'1'而非数字1
    expect(response.body.total).toBeGreaterThanOrEqual(0);
  });

  test('无token返回401', async () => {
    const response = await request(app)
      .get('/api/users');
    expect(response.status).toBe(401);
    // 特征记录：错误响应使用 legacy 格式
    expect(response.body).toHaveProperty('error');
    expect(response.body).toHaveProperty('code', 'AUTH_FAILED');
  });

  test('page参数超过范围时返回空数组而非404', async () => {
    const response = await request(app)
      .get('/api/users?page=99999')
      .set('Authorization', 'Bearer test-token-admin');

    expect(response.status).toBe(200);
    expect(response.body.users).toEqual([]);
    // 关键发现：page=99999不报错，返回空——外部系统依赖此行为
  });
});
```

### 3.2 运行并确认测试通过

```bash
npx jest test/characterization/ --verbose
```

**预期输出**：

```
PASS test/characterization/users.test.js
  GET /api/users - 特征测试 (勿修改)
    ✓ 返回200和用户列表数组 (145 ms)
    ✓ 无token返回401 (32 ms)
    ✓ page参数超过范围时返回空数组而非404 (28 ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
```

### 3.3 批量覆盖所有路由

```
请按照上面的模式，为以下所有路由模块生成特征测试：
1. routes/orders.js
2. routes/auth.js
3. routes/products.js
4. routes/reports.js (这个最复杂，请特别关注边缘情况)

每个模块的测试必须覆盖：
- 正常请求路径
- 认证失败
- 参数验证
- 错误处理路径
- 任何你发现的"意外行为"（在注释中标注）
```

> **常见问题**：特征测试在CI中不稳定？
> **解决方案**：使用数据库快照而非实时数据。Claude Code可以帮你创建fixture文件：

```
请创建 test/fixtures/ 目录，为每个集合生成测试数据快照。
数据量控制在每集合20-50条记录，覆盖所有已知的字段变体。
```

---

## 四、第三步：依赖映射与影响分析

### 4.1 构建依赖热力图

```
请分析项目中所有模块之间的依赖关系，按以下维度评分（1-10）：
1. 入度（被多少模块依赖）
2. 出度（依赖多少模块）
3. 变更频率（git log统计）
4. 测试覆盖率
5. 业务关键度

输出为一个Markdown表格，按综合风险分排序
```

**预期输出**：

| 模块 | 入度 | 出度 | 变更频率 | 测试覆盖 | 业务关键度 | 风险分 |
|------|------|------|----------|----------|------------|--------|
| utils/db.js | 12 | 2 | 低 | 5% | 极高 | **9.2** |
| middleware/auth.js | 8 | 1 | 中 | 0% | 极高 | **8.8** |
| routes/reports.js | 1 | 6 | 高 | 0% | 高 | **7.5** |
| utils/cache.js | 6 | 0 | 中 | 0% | 中 | **6.1** |
| routes/users.js | 0 | 3 | 中 | 45% | 中 | **4.2** |

### 4.2 确定迁移顺序

基于依赖分析，制定迁移优先级：

```mermaid
graph TD
    subgraph "Phase 1: 基础层（低风险高价值）"
        P1A[utils/db.js → Mongoose封装]
        P1B[utils/cache.js → Redis封装]
        P1C[middleware/auth.js → JWT标准化]
    end
    subgraph "Phase 2: 业务路由层"
        P2A[routes/users.js → TypeScript]
        P2B[routes/orders.js → TypeScript]
        P2C[routes/products.js → TypeScript]
    end
    subgraph "Phase 3: 复杂模块（最后攻坚）"
        P3A[routes/reports.js → 分层重构]
        P3B[共享状态清理]
    end

    P1A --> P2A
    P1A --> P2B
    P1B --> P2C
    P1C --> P2A
    P1C --> P2B
    P2A --> P3A
    P2B --> P3A
    P2C --> P3B

    style P1A fill:#4ecdc4,color:#fff
    style P1B fill:#4ecdc4,color:#fff
    style P1C fill:#4ecdc4,color:#fff
    style P3A fill:#ff6b6b,color:#fff
    style P3B fill:#ff6b6b,color:#fff
```

**核心原则**：先迁移被依赖最多的底层模块，最后迁移依赖最多的业务模块。这确保了每个阶段的变更影响范围最小。

---

## 五、第四步：Strangler Fig增量迁移实战

Strangler Fig（绞杀者无花果）模式的核心思想：逐步用新系统替换旧系统，每次替换一个可验证的小片段，旧系统持续运行直到完全被替换。

### 5.1 创建迁移分支策略

```bash
# 主分支保持稳定
git checkout main
git checkout -b migration/phase1-infrastructure

# 每个Phase完成后合并回main
# Phase内部使用短生命周期分支
```

### 5.2 迁移Phase 1：数据库访问层

**目标**：将散落在路由中的MongoDB直接调用统一封装到Repository层。

在Claude Code中：

```
请执行以下重构任务：

1. 在 src/repositories/ 创建 UserRepository.js
2. 从 routes/users.js 中提取所有MongoDB查询操作
3. 使用Mongoose模型替代原始MongoDB驱动调用
4. 确保所有特征测试仍然通过
5. 不改变任何API行为

约束：
- 保持函数签名不变
- 错误处理方式与原有一致
- 每完成一个函数，运行测试确认
```

Claude Code生成的Repository示例：

```javascript
// src/repositories/UserRepository.js
const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  username: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  role: { type: String, enum: ['admin', 'user', 'viewer'], default: 'user' },
  createdAt: { type: Date, default: Date.now },
  // 保留遗留字段（即使不在schema中，也允许存在）
}, { strict: false }); // strict:false 确保兼容遗留数据

const User = mongoose.model('User', UserSchema);

class UserRepository {
  async findAll({ page = 1, limit = 20 } = {}) {
    // 特征保持：page参数作为字符串传入（遗留兼容）
    const skip = (parseInt(page) - 1) * limit;
    const [users, total] = await Promise.all([
      User.find({}).skip(skip).limit(limit).lean(),
      User.countDocuments({})
    ]);
    return {
      users,
      page: String(page), // 保持字符串返回
      total,
      totalPages: Math.ceil(total / limit)
    };
  }

  async findById(id) {
    return User.findById(id).lean();
  }

  async findByEmail(email) {
    return User.findOne({ email }).lean();
  }
}

module.exports = new UserRepository();
```

### 5.3 逐步替换——路由层调用新Repository

```
请修改 routes/users.js，将直接MongoDB调用替换为 UserRepository 的方法调用。
要求：
1. 逐个函数替换，每次替换后运行测试
2. 保持所有错误处理路径不变
3. 删除不再使用的旧代码
4. 添加 @migration 标记注释
```

替换后的路由：

```javascript
// routes/users.js (Phase 1 迁移后)
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const UserRepository = require('../repositories/UserRepository'); // @migration: 新增

// @migration: 原始MongoDB查询已提取到UserRepository
router.get('/api/users', auth.requireAuth, async (req, res) => {
  try {
    const result = await UserRepository.findAll({
      page: req.query.page,
      limit: req.query.limit
    });
    res.json(result);
  } catch (error) {
    // 保持原有错误格式
    res.status(500).json({ error: error.message, code: 'DB_ERROR' });
  }
});

module.exports = router;
```

### 5.4 验证迁移安全性

每次替换后执行：

```bash
# 运行特征测试——确保行为未变
npx jest test/characterization/ --verbose

# 运行所有测试
npm test

# 检查代码覆盖率变化
npx jest --coverage --coverageReporters=text-summary
```

```
请对比迁移前后的测试结果：
1. 所有特征测试是否全部通过？
2. 是否有任何响应字段发生变化？
3. 错误处理路径是否完整保留？
4. 列出所有 @migration 标记的位置
```

---

## 六、第五步：Worktree并行重构——多条迁移流同时推进

当Phase 1完成后，多个独立的模块可以**并行迁移**。这是Claude Code的worktree功能大显身手的时刻。

### 6.1 Worktree并行架构

```mermaid
graph TB
    MAIN[main分支<br/>稳定基准] --> WT1[worktree: migrate-orders<br/>Claude会话1]
    MAIN --> WT2[worktree: migrate-products<br/>Claude会话2]
    MAIN --> WT3[worktree: migrate-auth<br/>Claude会话3]

    WT1 -->|PR #1| REVIEW1[Code Review]
    WT2 -->|PR #2| REVIEW2[Code Review]
    WT3 -->|PR #3| REVIEW3[Code Review]

    REVIEW1 --> MERGE[合并到main]
    REVIEW2 --> MERGE
    REVIEW3 --> MERGE
```

### 6.2 启动并行Worktree会话

```bash
# 终端1：迁移orders模块
cd legacy-project/
git worktree add .claude/worktrees/migrate-orders -b migrate-orders
cd .claude/worktrees/migrate-orders
claude

# 终端2：迁移products模块
cd legacy-project/
git worktree add .claude/worktrees/migrate-products -b migrate-products
cd .claude/worktrees/migrate-products
claude

# 终端3：迁移auth模块
cd legacy-project/
git worktree add .claude/worktrees/migrate-auth -b migrate-auth
cd .claude/worktrees/migrate-auth
claude
```

### 6.3 每个Worktree中的迁移提示词

在每个Claude Code会话中，使用结构化的迁移指令：

**终端1（orders迁移）**：

```
你正在一个隔离的worktree中工作。任务：迁移 routes/orders.js

## 上下文
- 请先读取 CLAUDE.md 了解项目结构
- Phase 1 已完成：数据库访问层已迁移到 repositories/
- 参考 routes/users.js 的迁移模式

## 具体步骤
1. 创建 src/repositories/OrderRepository.js
2. 提取所有MongoDB查询到Repository
3. 将callback模式改为async/await
4. 确保所有特征测试通过
5. 不修改API接口签名

## 完成标准
- npm test 全部通过
- 无ESLint错误
- 每个迁移点有 @migration 注释
```

**终端2（products迁移）**——类似的指令，但针对products模块。

### 6.4 解决合并冲突

当多个Worktree完成并合并时，可能产生冲突：

```bash
# 合并第一个PR后
git checkout main
git merge migrate-orders

# 合并第二个时检查冲突
git merge migrate-products
# 如果有冲突，让Claude Code帮助解决：

claude -p "解决当前的git合并冲突。优先保留两个分支的功能代码，去除重复的import语句。合并后运行测试确认。"
```

---

## 七、第六步：TypeScript渐进迁移

### 7.1 JSDoc先行策略

不完全切换到TypeScript，而是先用JSDoc注解为遗留代码添加类型：

```
请为 src/repositories/ 目录下的所有文件添加JSDoc类型注解。
要求：
1. 每个函数的参数和返回值都要有类型注解
2. 定义接口类型（用 @typedef）
3. 标注可能的 null/undefined 返回
4. 不改变运行时行为
```

```javascript
/**
 * @typedef {Object} PaginatedResult
 * @property {Object[]} users - 用户列表
 * @property {string} page - 当前页码（字符串格式，遗留兼容）
 * @property {number} total - 总记录数
 * @property {number} totalPages - 总页数
 */

/**
 * 查询所有用户（分页）
 * @param {{ page?: string|number, limit?: number }} options
 * @returns {Promise<PaginatedResult>}
 */
async findAll({ page = 1, limit = 20 } = {}) {
  // ...
}
```

### 7.2 逐文件.ts迁移

当JSDoc覆盖完整后，逐步转换为.ts：

```
请将 UserRepository.js 转换为 TypeScript：
1. 文件重命名为 UserRepository.ts
2. JSDoc注解转为正式类型定义
3. 创建 src/types/ 目录存放共享类型
4. 确保 tsconfig.json 配置允许JS（allowJs: true）
5. 运行 tsc --noEmit 检查类型错误
```

---

## 八、实战案例：完整的Node.js遗留系统迁移

以下是一个完整的迁移项目执行记录，从接到项目到全部完成。

### 8.1 项目背景

| 项目属性 | 详情 |
|----------|------|
| 类型 | 内部管理后台API |
| 技术栈 | Express 4 + MongoDB + EJS |
| 代码行数 | ~28,000行 |
| 活跃时间 | 2019-2025 |
| 测试覆盖率 | 12% |
| 开发者数 | 8人（不同时期） |
| 迁移目标 | Express 5 + TypeScript + Mongoose + 70%测试覆盖率 |

### 8.2 完整执行时间线

```mermaid
gantt
    title 遗留系统迁移时间线（实际执行记录）
    dateFormat  YYYY-MM-DD
    axisFormat  %m/%d

    section Phase 0: 准备
    代码考古与架构分析           :done, p0a, 2026-03-01, 2d
    CLAUDE.md定制               :done, p0b, after p0a, 1d
    特征测试生成                 :done, p0c, after p0b, 3d

    section Phase 1: 基础层
    MongoDB→Mongoose封装         :done, p1a, 2026-03-08, 3d
    缓存层重构                   :done, p1b, after p1a, 2d
    认证中间件标准化             :done, p1c, after p1b, 2d

    section Phase 2: 路由层
    users模块迁移(Worktree 1)    :done, p2a, 2026-03-16, 2d
    orders模块迁移(Worktree 2)   :done, p2b, 2026-03-16, 3d
    products模块迁移(Worktree 3) :done, p2c, 2026-03-16, 2d
    合并集成                     :done, p2d, after p2b, 1d

    section Phase 3: 攻坚
    reports模块分层重构          :active, p3a, 2026-03-22, 5d
    共享状态清理                 :p3b, after p3a, 3d
    TypeScript迁移               :p3c, after p3b, 4d

    section Phase 4: 验证
    全面集成测试                 :p4a, after p3c, 2d
    性能基准对比                 :p4b, after p4a, 1d
```

### 8.3 关键迁移命令清单

```bash
# ===== Day 1-2: 代码考古 =====
claude  # 进入交互模式
> /init
> 分析项目架构，识别所有路由、模型、中间件
> 生成依赖热力图和迁移优先级

# ===== Day 3: 特征测试 =====
> 为所有路由生成特征测试
npx jest test/characterization/ --verbose
git add test/characterization/
git commit -m "feat: add characterization tests for all routes"

# ===== Day 4-6: Phase 1 基础层 =====
> 创建 repositories/UserRepository.js, 提取MongoDB查询
> 替换 routes/users.js 中的数据库调用
npx jest test/characterization/ --verbose  # 确认行为不变
git commit -m "refactor: extract UserRepository from routes"

# ===== Day 7-9: Phase 1 完成 =====
> 创建 repositories/OrderRepository.js, ProductRepository.js
> 重构 middleware/auth.js 使用JWT
npm test
git commit -m "refactor: complete infrastructure layer migration"

# ===== Day 10+: 并行Worktree =====
git worktree add .claude/worktrees/wt-orders -b feat/migrate-orders
git worktree add .claude/worktrees/wt-products -b feat/migrate-products
# 在每个worktree中启动独立的claude会话

# ===== 合并与验证 =====
git checkout main
git merge feat/migrate-orders
git merge feat/migrate-products
npm test
```

### 8.4 迁移前后对比

| 指标 | 迁移前 | 迁移后 |
|------|--------|--------|
| Express版本 | 4.17 | 5.1 |
| 语言 | JavaScript ES5 | TypeScript 5.x |
| 数据访问 | MongoDB原生驱动散落各处 | Mongoose Repository模式 |
| 异步模式 | callback嵌套 | async/await |
| 测试覆盖率 | 12% | 78% |
| 平均响应时间 | 340ms | 285ms |
| ESLint错误 | 847个 | 0个 |
| 循环依赖 | 14处 | 0处 |
| 全局变量 | 23个 | 0个 |

---

## 九、高级技巧与陷阱规避

### 9.1 上下文窗口管理策略

大型遗留代码库（>100K token）无法一次全部加载。使用**分区域扫描**策略：

```
请按以下策略管理上下文：
1. 先读取 CLAUDE.md（始终保持在上下文中）
2. 只加载当前正在迁移的模块及其直接依赖
3. 每完成一个模块，总结关键决策到 CLAUDE.md
4. 用 /compact 命令压缩历史对话，保留关键上下文
```

### 9.2 隐式行为捕获技巧

遗留代码最危险的不是显式逻辑，而是隐式行为：

```
请帮我找出 routes/reports.js 中所有的隐式行为：
1. 依赖全局变量的副作用
2. 依赖执行顺序的初始化逻辑
3. 未处理的错误被静默吞掉的情况
4. 依赖特定MongoDB版本的查询行为
5. 依赖时区的日期处理
```

### 9.3 回滚策略

每次重大迁移前创建Git标签：

```bash
# Phase开始前打标签
git tag pre-phase-1
git tag pre-phase-2

# 如果出问题，精确回滚
git reset --hard pre-phase-1
```

或者在Claude Code中：

```
请检查最近的迁移是否引入了回归。对比特征测试结果：
1. 运行所有特征测试
2. 对比API响应与基线快照
3. 如果发现差异，列出具体变化
4. 生成回滚补丁（git revert格式）
```

### 9.4 五个致命陷阱

| 陷阱 | 症状 | 解决方案 |
|------|------|----------|
| **过度迁移** | 一次改太多，测试全红 | 每次只迁移一个函数/模块 |
| **忽略时序依赖** | 初始化顺序错乱 | 用依赖注入替代全局变量 |
| **特征测试不够全面** | 迁移后线上出bug | 补充边缘情况和错误路径测试 |
| **Worktree同步失败** | 合并冲突成灾 | 频繁从main拉取更新 |
| **CLAUDE.md过时** | Claude做出错误决策 | 每完成一个Phase更新一次 |

---

## 十、CLAUDE.md维护——迁移过程的"活文档"

迁移过程中，`CLAUDE.md`应该持续更新。建议在文件末尾维护迁移日志：

```markdown
## 迁移日志

### Phase 1 完成 (2026-03-10)
- UserRepository: 完成, 5个方法迁移
- OrderRepository: 完成, 8个方法迁移
- ProductRepository: 完成, 6个方法迁移
- 全局变量: cache对象已替换为Redis封装
- ⚠️ 注意: UserRepository.findAll() 的page参数仍返回字符串

### Phase 2 进行中 (2026-03-16)
- routes/users.js: ✅ 已迁移到TypeScript
- routes/orders.js: 🔄 进行中（Worktree: wt-orders）
- routes/products.js: 🔄 进行中（Worktree: wt-products）
- routes/reports.js: ⏳ 未开始（最高风险，最后处理）

### 已知遗留问题
- [ ] reports模块的"华东区域特殊折扣"逻辑需要业务确认
- [ ] auth中间件的token刷新机制需要重设计
- [ ] 部分EJS模板仍引用已删除的全局变量
```

---

## 十一、自动化迁移流水线

将迁移验证集成到CI/CD中：

```yaml
# .github/workflows/migration-check.yml
name: Migration Safety Check

on: [pull_request]

jobs:
  characterization-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - name: Run characterization tests
        run: npx jest test/characterization/ --verbose --json --outputFile=results.json
      - name: Compare API responses
        run: |
          node scripts/compare-snapshots.js
      - name: Check coverage threshold
        run: |
          npx jest --coverage --coverageThreshold='{"global":{"branches":70,"functions":70,"lines":70}}'

  regression-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: API contract verification
        run: |
          npx newman run test/postman/legacy-api-collection.json
```

---

## 延伸阅读

- **《Working Effectively with Legacy Code》**（Michael Feathers）——特征测试概念的经典来源，所有AI辅助迁移的理论基础
- **Anthropic官方Best Practices** ([code.claude.com/docs/en/best-practices](https://code.claude.com/docs/en/best-practices))——上下文窗口管理和大型代码库操作指南
- **Strangler Fig Pattern** ([martinfowler.com/bliki/StranglerFigApplication.html](https://martinfowler.com/bliki/StranglerFigApplication.html))——Martin Fowler对增量迁移模式的原始定义
- **Claude Code Worktrees文档** ([code.claude.com/docs/en/worktrees](https://code.claude.com/docs/en/worktrees))——并行会话隔离的官方配置方法

---

## 训练营适用性评估

| 维度 | 评估 |
|------|------|
| **适合训练营类型** | 企业内训（遗留系统迁移）、高级开发者训练营、AI辅助工程实战营 |
| **教学时长** | 4-6小时（含实操），建议分两个半天 |
| **前置要求** | 学员需有Node.js基础和Git操作经验，已安装Claude Code |
| **实操比例** | 60%实操 + 30%讲解 + 10%讨论 |
| **硬件要求** | 每人一台笔记本，网络通畅，Claude Code API额度充足 |
| **最佳班级规模** | 10-20人（需要助教支持Worktree操作） |
| **考核方式** | 提交一个完成的Phase迁移PR，包含特征测试和迁移代码 |

---

## 参考来源

1. [My Claude Code Workflow for Refactoring a Legacy Codebase](https://crystl.dev/blog/refactoring-legacy-codebase/) — 真实Node.js遗留项目迁移案例，含worktree并行策略
2. [Claude Code for Legacy Codebases: A Practitioner's Guide](https://richardporter.dev/blog/claude-code-legacy-codebase-practitioners-guide) — CLAUDE.md配置、上下文管理与增量工作流深度指南
3. [Claude for Legacy Code Refactoring](https://claudereadiness.com/blog/claude-legacy-code-refactoring/) — 特征测试生成、依赖映射、增量现代化系统方法
4. [How Claude Code Changes Legacy Code Refactoring](https://nazarboyko.com/articles/how-claude-code-changes-legacy-code-refactoring) — 遗留重构vs重写的区别分析，风险控制方法论
5. [Legacy Modernization with Claude Code Playbook](https://ao92265.github.io/claude-code-playbook/docs/legacy-modernization/) — 1M token上下文窗口在代码考古中的应用策略

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
