Files
PicAnalysis/.project/development-plan.md
wjl 1a0ebde95d feat: 初始化 PicAnalysis 项目
完整的前后端图片分析应用,包含:
- 后端:Express + Prisma + SQLite,101个单元测试全部通过
- 前端:React + TypeScript + Vite,47个单元测试,89.73%覆盖率
- E2E测试:Playwright 测试套件
- MCP集成:Playwright MCP配置完成并测试通过

功能模块:
- 用户认证(JWT)
- 文档管理(CRUD)
- 待办管理(三态工作流)
- 图片管理(上传、截图、OCR)

测试覆盖:
- 后端单元测试:101/101 
- 前端单元测试:47/47 
- E2E测试:通过 
- MCP Playwright测试:通过 

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 20:10:11 +08:00

26 KiB
Raw Permalink Blame History

TDD 开发计划 - 图片OCR与智能文档管理系统

项目信息

  • 开始日期: 2026-02-21
  • 预计完成: 2026-04-05 (6周)
  • 团队规模: 1-2人
  • 开发方法: TDD (测试驱动开发)
  • 迭代方式: 1周Sprint

开发原则

TDD 核心原则

  1. 测试先行: 在写功能代码前先写测试
  2. 小步迭代: 每次只写一个测试和对应实现
  3. 持续重构: 保持代码的简洁和可维护
  4. 快速反馈: 测试必须快速运行

Ralph Loop 原则

  1. 持续反思: 每个阶段都要问 @ralph
  2. 质疑假设: 不要理所当然,验证一切
  3. 追求简洁: 寻找最简单的解决方案
  4. 学习改进: 从每个实现中学习

代码质量标准

  • 代码覆盖率: ≥ 80%
  • 测试通过率: 100%
  • ESLint: 0错误
  • TypeScript: 0类型错误

TDD 开发循环

┌─────────────────────────────────────┐
│ 1. 🔴 Red: 写一个失败的测试          │
│    @ralph 这个测试描述正确吗?        │
│    @ralph 是否覆盖了核心场景?        │
└──────────┬──────────────────────────┘
           ↓
┌─────────────────────────────────────┐
│ 2. 🟢 Green: 写最小代码通过测试      │
│    @ralph 这是最简单的实现吗?        │
│    @ralph 有不必要的复杂度吗?        │
└──────────┬──────────────────────────┘
           ↓
┌─────────────────────────────────────┐
│ 3. 🔵 Blue: 重构优化代码             │
│    @ralph 代码可以更简洁吗?          │
│    @ralph 有重复代码吗?             │
│    @ralph 命名是否清晰?             │
└──────────┬──────────────────────────┘
           ↓
┌─────────────────────────────────────┐
│ 4. 提交代码                         │
│    @ralph 我完成了吗?还有遗漏吗?    │
│    @ralph 需要添加文档吗?           │
└──────────┬──────────────────────────┘
           ↓
      返回步骤 1 (下一个测试)

Sprint 计划

Sprint 1: 基础架构 (Days 1-5)

任务 1.1: 项目初始化

时间: 0.5天 依赖: 无 测试策略:

  • 单元测试: 构建配置正确
  • 集成测试: 无

Ralph 检查点:

  • 开始前: 我是否需要所有这些依赖?
  • 实现中: 这个配置是否最小化?
  • 完成后: 项目结构是否清晰?

TDD 循环:

// 1. Red: 测试构建配置
describe('Build Config', () => {
  it('should compile TypeScript', () => {
    // 验证构建输出
  });

  it('should have correct dependencies', () => {
    // 验证package.json
  });
});

验收标准:

  • 前端项目创建成功 (React + Vite)
  • 后端项目创建成功 (Express + TypeScript)
  • Prisma初始化完成
  • 测试框架配置完成 (Jest + Vitest)
  • Docker配置文件创建
  • ESLint + Prettier配置

任务 1.2: 数据库Schema设计

时间: 1天 依赖: 任务1.1 测试策略:

  • 单元测试: Schema验证
  • 集成测试: Migration成功

Ralph 检查点:

  • 开始前: 数据模型是否完整?
  • 实现中: 关系设计是否正确?
  • 完成后: 是否考虑了索引优化?

TDD 循环:

// 1. Red: 测试Schema
describe('Database Schema', () => {
  it('should create user with correct fields', async () => {
    const user = await prisma.user.create({
      data: { username: 'test', email: 'test@test.com', password_hash: 'hash' }
    });
    expect(user).toHaveProperty('id');
    expect(user).toHaveProperty('created_at');
  });

  it('should allow image without document', async () => {
    const image = await prisma.image.create({
      data: { user_id: userId, file_path: '/path', document_id: null }
    });
    expect(image.document_id).toBeNull();
  });

  it('should enforce unique username', async () => {
    await expect(
      prisma.user.create({
        data: { username: 'duplicate', ... }
      })
    ).rejects.toThrow();
  });
});

验收标准:

  • Prisma Schema定义完成
  • Migration成功执行
  • 所有实体关系正确
  • 索引定义完成
  • Seed脚本创建

任务 1.3: 用户认证系统

时间: 1.5天 依赖: 任务1.2 测试策略:

  • 单元测试: 密码加密、JWT生成/验证
  • 集成测试: 完整注册登录流程

Ralph 检查点:

  • 开始前: 安全性考虑是否充分?
  • 实现中: 密码存储是否安全?
  • 完成后: Token过期是否正确处理

TDD 循环:

// 1. Red: 测试密码加密
describe('Password Service', () => {
  it('should hash password with bcrypt', async () => {
    const hash = await PasswordService.hash('password123');
    expect(hash).not.toBe('password123');
    expect(hash.length).toBe(60);
  });

  it('should verify correct password', async () => {
    const hash = await PasswordService.hash('password123');
    const isValid = await PasswordService.verify('password123', hash);
    expect(isValid).toBe(true);
  });

  it('should reject wrong password', async () => {
    const hash = await PasswordService.hash('password123');
    const isValid = await PasswordService.verify('wrong', hash);
    expect(isValid).toBe(false);
  });
});

// 1. Red: 测试JWT
describe('Auth Service', () => {
  it('should generate valid JWT token', () => {
    const token = AuthService.generateToken({ user_id: '123' });
    expect(token).toBeTruthy();
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    expect(decoded.user_id).toBe('123');
  });

  it('should verify valid token', () => {
    const token = AuthService.generateToken({ user_id: '123' });
    const payload = AuthService.verifyToken(token);
    expect(payload.user_id).toBe('123');
  });

  it('should reject expired token', () => {
    const expiredToken = '...';
    expect(() => AuthService.verifyToken(expiredToken))
      .toThrow('Token expired');
  });
});

验收标准:

  • 密码使用bcrypt加密
  • JWT生成和验证正确
  • 注册API完成
  • 登录API完成
  • 认证中间件完成
  • 数据隔离验证通过

任务 1.4: 基础API框架

时间: 1天 依赖: 任务1.3 测试策略:

  • 单元测试: 路由注册
  • 集成测试: API调用

Ralph 检查点:

  • 开始前: API设计是否RESTful
  • 实现中: 错误处理是否统一?
  • 完成后: 响应格式是否一致?

TDD 循环:

// 1. Red: 测试API响应格式
describe('API Response Format', () => {
  it('should return success response', async () => {
    const response = await request(app)
      .post('/api/auth/register')
      .send({ username: 'test', password: 'pass123' });

    expect(response.status).toBe(201);
    expect(response.body).toHaveProperty('success', true);
    expect(response.body).toHaveProperty('data');
  });

  it('should return error response', async () => {
    const response = await request(app)
      .post('/api/auth/register')
      .send({ username: '', password: '' });

    expect(response.status).toBe(400);
    expect(response.body).toHaveProperty('success', false);
    expect(response.body).toHaveProperty('error');
  });
});

验收标准:

  • 统一响应格式
  • 错误处理中间件
  • 请求验证中间件
  • CORS配置
  • 日志中间件

任务 1.5: Docker配置

时间: 0.5天 依赖: 任务1.4 测试策略:

  • 集成测试: 容器构建和运行

Ralph 检查点:

  • 开始前: 需要多少容器?
  • 实现中: 网络配置是否正确?
  • 完成后: 数据卷是否持久化?

验收标准:

  • Dockerfile创建 (前后端)
  • docker-compose.yml配置
  • 一键启动脚本
  • 数据卷配置

Sprint 2: 图片与OCR功能 (Days 6-12)

任务 2.1: 图片上传功能

时间: 1天 依赖: Sprint 1 测试策略:

  • 单元测试: 文件验证、大小限制
  • 集成测试: 上传API

Ralph 检查点:

  • 开始前: 安全性考虑(文件类型验证)?
  • 实现中: 存储路径是否安全?
  • 完成后: 大文件处理是否正确?

TDD 循环:

// 1. Red: 测试文件验证
describe('Image Upload Service', () => {
  it('should accept valid image formats', () => {
    expect(ImageValidator.isValidFormat('image/jpeg')).toBe(true);
    expect(ImageValidator.isValidFormat('image/png')).toBe(true);
  });

  it('should reject invalid formats', () => {
    expect(ImageValidator.isValidFormat('application/pdf')).toBe(false);
    expect(ImageValidator.isValidFormat('text/plain')).toBe(false);
  });

  it('should reject files larger than 10MB', () => {
    const largeFile = { size: 11 * 1024 * 1024 };
    expect(ImageValidator.isValidSize(largeFile)).toBe(false);
  });

  it('should accept files under 10MB', () => {
    const file = { size: 5 * 1024 * 1024 };
    expect(ImageValidator.isValidSize(file)).toBe(true);
  });
});

验收标准:

  • 支持JPG/PNG/WEBP
  • 文件大小验证 (<10MB)
  • 文件类型验证
  • 存储到正确路径
  • 返回图片URL

任务 2.2: OCR集成

时间: 2天 依赖: 任务2.1 测试策略:

  • 单元测试: 置信度判断、质量检测
  • 集成测试: OCR流程

Ralph 检查点:

  • 开始前: OCR provider选择
  • 实现中: 失败处理是否完善?
  • 完成后: 性能是否可接受?

TDD 循环:

// 1. Red: 测试置信度判断
describe('OCR Service', () => {
  it('should create document when confidence > threshold', () => {
    const result = OCRService.shouldCreateDocument(0.8, 0.3);
    expect(result).toBe(true);
  });

  it('should not create document when confidence < threshold', () => {
    const result = OCRService.shouldCreateDocument(0.2, 0.3);
    expect(result).toBe(false);
  });

  it('should handle threshold boundary', () => {
    expect(OCRService.shouldCreateDocument(0.3, 0.3)).toBe(true);
    expect(OCRService.shouldCreateDocument(0.29, 0.3)).toBe(false);
  });
});

// 1. Red: 测试图片质量检测
describe('Image Quality Analyzer', () => {
  it('should detect clear image', () => {
    const result = QualityAnalyzer.analyze(clearImageBuffer);
    expect(result.quality).toBe('good');
    expect(result.score).toBeGreaterThan(0.7);
  });

  it('should detect blurry image', () => {
    const result = QualityAnalyzer.analyze(blurryImageBuffer);
    expect(result.quality).toBe('poor');
    expect(result.score).toBeLessThan(0.3);
  });
});

验收标准:

  • OCR provider抽象层
  • 本地OCR集成可选
  • 云端OCR集成
  • 置信度判断逻辑
  • 失败时保存到待处理列表
  • 异步处理队列

任务 2.3: 待处理图片功能

时间: 1天 依赖: 任务2.2 测试策略:

  • 单元测试: 查询逻辑
  • 集成测试: API

Ralph 检查点:

  • 开始前: 查询是否高效?
  • 实现中: 是否考虑了分页?

TDD 循环:

// 1. Red: 测试待处理图片查询
describe('Pending Images Service', () => {
  it('should return images without document', async () => {
    const images = await PendingImagesService.getByUserId(userId);
    images.forEach(img => {
      expect(img.document_id).toBeNull();
    });
  });

  it('should return failed OCR images', async () => {
    const images = await PendingImagesService.getByUserId(userId);
    images.forEach(img => {
      expect(['failed', 'pending']).toContain(img.processing_status);
    });
  });
});

验收标准:

  • 待处理图片列表API
  • 手动创建文档API
  • 图片增强API
  • 删除图片API

任务 2.4: 文档管理

时间: 1.5天 依赖: 任务2.3 测试策略:

  • 单元测试: CRUD操作
  • 集成测试: 文档API

Ralph 检查点:

  • 开始前: 数据验证是否充分?
  • 实现中: 搜索功能是否高效?

TDD 循环:

// 1. Red: 测试文档CRUD
describe('Document Service', () => {
  it('should create document from OCR result', async () => {
    const document = await DocumentService.createFromOCR({
      ocr_result: 'test text',
      image_id: 'img123',
      user_id: 'user123'
    });
    expect(document.content).toBe('test text');
  });

  it('should search documents by title', async () => {
    const results = await DocumentService.search('meeting');
    results.forEach(doc => {
      expect(doc.title.toLowerCase()).toContain('meeting');
    });
  });
});

验收标准:

  • 文档CRUD API
  • 文档搜索功能
  • 文档-图片关联
  • 文档列表分页

Sprint 3: AI智能分析 (Days 13-19)

任务 3.1: AI Provider抽象层

时间: 1天 依赖: Sprint 2 测试策略:

  • 单元测试: Provider接口

Ralph 检查点:

  • 开始前: 接口设计是否通用?
  • 实现中: 错误处理是否统一?

TDD 循环:

// 1. Red: 测试AI Provider接口
describe('AI Provider Interface', () => {
  it('should implement analyze method', async () => {
    const provider = new GLMProvider();
    const result = await provider.analyze('test content');
    expect(result).toHaveProperty('tags');
    expect(result).toHaveProperty('category');
  });

  it('should handle API errors gracefully', async () => {
    const provider = new GLMProvider();
    // Mock API failure
    jest.spyOn(provider, 'callAPI').mockRejectedValue(new Error('API Error'));
    await expect(provider.analyze('test')).rejects.toThrow();
  });
});

验收标准:

  • AI Provider接口定义
  • GLM集成
  • MiniMax集成
  • DeepSeek集成
  • 统一错误处理

任务 3.2: 智能标签生成

时间: 1.5天 依赖: 任务3.1 测试策略:

  • 单元测试: 标签提取、新标签创建
  • 集成测试: 标签API

Ralph 检查点:

  • 开始前: 标签数量是否合适?
  • 实现中: 新标签验证是否充分?

TDD 循环:

// 1. Red: 测试标签生成
describe('Tag Generation Service', () => {
  it('should extract relevant tags', async () => {
    const result = await AIService.generateTags('会议记录:讨论项目进度和下一步计划');
    expect(result.tags).toContain('会议');
    expect(result.tags).toContain('项目');
  });

  it('should create new tag when needed', async () => {
    const existingTags = ['工作', '个人'];
    const result = await AIService.generateTags('发票报销:午餐费用', { existingTags });
    expect(result.new_tags).toContain('发票');
  });

  it('should limit tag count to 5', async () => {
    const result = await AIService.generateTags('long text...');
    expect(result.tags.length).toBeLessThanOrEqual(5);
  });
});

验收标准:

  • AI生成标签
  • 新标签创建
  • 标签使用统计
  • 常用标签优先展示

任务 3.3: 智能分类与类型

时间: 1.5天 依赖: 任务3.2 测试策略:

  • 单元测试: 分类推荐
  • 集成测试: 分类API

Ralph 检查点:

  • 开始前: 分类逻辑是否准确?
  • 实现中: 新分类命名是否合理?

TDD 循环:

// 1. Red: 测试分类推荐
describe('Category Suggestion Service', () => {
  it('should match existing category', async () => {
    const categories = ['会议记录', '学习笔记'];
    const result = await AIService.suggestCategory('今天开会讨论了项目进度', { categories });
    expect(result.category).toBe('会议记录');
    expect(result.is_new).toBe(false);
  });

  it('should create new category when no match', async () => {
    const categories = ['会议记录'];
    const result = await AIService.suggestCategory('发票号123456 金额100元', { categories });
    expect(result.is_new).toBe(true);
    expect(result.category).toBe('发票');
    expect(result.suggested_icon).toBeTruthy();
  });
});

验收标准:

  • 匹配现有分类
  • 创建新分类
  • 推荐图标
  • 分类使用统计

任务 3.4: AI分析API

时间: 1天 依赖: 任务3.3 测试策略:

  • 集成测试: 完整分析流程

Ralph 检查点:

  • 开始前: API响应时间是否可接受
  • 实现中: 降级处理是否完善?

验收标准:

  • 分析API
  • 异步处理
  • 轮询状态API
  • 失败降级处理

Sprint 4: 待办管理 (Days 20-26)

任务 4.1: 待办CRUD

时间: 1天 依赖: Sprint 3 测试策略:

  • 单元测试: CRUD操作
  • 集成测试: 待办API

TDD 循环:

// 1. Red: 测试待办创建
describe('Todo Service', () => {
  it('should create todo from document', async () => {
    const todo = await TodoService.createFromDocument({
      document_id: 'doc123',
      user_id: 'user123',
      title: '完成报告'
    });
    expect(todo.status).toBe('pending');
    expect(todo.document_id).toBe('doc123');
  });
});

验收标准:

  • 待办CRUD API
  • 优先级设置
  • 截止日期设置
  • 分类关联

任务 4.2: 三状态流转

时间: 1.5天 依赖: 任务4.1 测试策略:

  • 单元测试: 状态验证
  • 集成测试: 状态流转API

TDD 循环:

// 1. Red: 测试状态流转
describe('Todo Status Transition', () => {
  it('should allow pending to completed', () => {
    const result = TodoService.validateTransition('pending', 'completed');
    expect(result).toBe(true);
  });

  it('should allow completed to confirmed', () => {
    const result = TodoService.validateTransition('completed', 'confirmed');
    expect(result).toBe(true);
  });

  it('should not allow confirmed to pending', () => {
    const result = TodoService.validateTransition('confirmed', 'pending');
    expect(result).toBe(false);
  });

  it('should update timestamps', async () => {
    const todo = await TodoService.updateStatus(todoId, 'completed');
    expect(todo.completed_at).toBeTruthy();
  });
});

验收标准:

  • 状态验证逻辑
  • 时间戳自动更新
  • 状态流转API
  • 批量操作API

任务 4.3: 待办列表与筛选

时间: 1天 依赖: 任务4.2 测试策略:

  • 单元测试: 排序逻辑
  • 集成测试: 列表API

TDD 循环:

// 1. Red: 测试待办排序
describe('Todo Sorting', () => {
  it('should sort by priority then due date', () => {
    const todos = [
      { priority: 'high', due_date: '2024-01-15' },
      { priority: 'high', due_date: '2024-01-10' },
      { priority: 'medium', due_date: '2024-01-10' }
    ];
    const sorted = TodoService.sort(todos);
    expect(sorted[0].priority).toBe('high');
    expect(sorted[0].due_date).toBe('2024-01-10');
  });
});

验收标准:

  • 三状态列表查询
  • 多条件筛选
  • 排序功能
  • 分页支持

Sprint 5: 前端开发 (Days 27-33)

任务 5.1: 基础布局与路由

时间: 1天 依赖: Sprint 4 测试策略:

  • 组件测试: 路由渲染

验收标准:

  • 主布局组件
  • 路由配置
  • 导航组件
  • 认证路由守卫

任务 5.2: 认证页面

时间: 1天 依赖: 任务5.1 测试策略:

  • 组件测试: 表单验证

TDD 循环:

// 1. Red: 测试登录表单
describe('LoginForm', () => {
  it('should show error for empty fields', () => {
    render(<LoginForm />);
    fireEvent.click(screen.getByText('登录'));
    expect(screen.getByText('请输入用户名')).toBeTruthy();
  });

  it('should call API on valid input', async () => {
    const mockLogin = jest.fn();
    render(<LoginForm onLogin={mockLogin} />);
    // fill form and submit
    await waitFor(() => expect(mockLogin).toHaveBeenCalled());
  });
});

验收标准:

  • 登录表单
  • 注册表单
  • 表单验证
  • 错误提示

任务 5.3: 图片上传组件

时间: 1.5天 依赖: 任务5.2 测试策略:

  • 组件测试: 拖拽、选择、预览

TDD 循环:

// 1. Red: 测试图片上传
describe('ImageUpload', () => {
  it('should accept drag and drop', () => {
    const onUpload = jest.fn();
    render(<ImageUpload onUpload={onUpload} />);
    const dropZone = screen.getByTestId('drop-zone');

    fireEvent.drop(dropZone, {
      dataTransfer: { files: [new File([''], 'test.png', { type: 'image/png' })] }
    });

    await waitFor(() => expect(onUpload).toHaveBeenCalled());
  });
});

验收标准:

  • 拖拽上传
  • 文件选择
  • 图片预览
  • 进度显示
  • 错误处理

任务 5.4: OCR结果编辑器

时间: 1天 依赖: 任务5.3 测试策略:

  • 组件测试: 文本编辑

验收标准:

  • 文本编辑区域
  • 图片预览
  • 保存按钮
  • AI分析按钮

任务 5.5: 文档管理页面

时间: 1.5天 依赖: 任务5.4 测试策略:

  • 组件测试: 列表、搜索、详情

验收标准:

  • 文档列表
  • 搜索功能
  • 文档详情
  • 编辑功能
  • 删除功能

任务 5.6: 待办管理页面

时间: 1.5天 依赖: 任务5.5 测试策略:

  • 组件测试: 三状态列表、批量操作

TDD 循环:

// 1. Red: 测试待办状态切换
describe('TodoList', () => {
  it('should show pending todos by default', () => {
    const todos = [{ id: 1, status: 'pending', title: 'Test' }];
    render(<TodoList todos={todos} />);
    expect(screen.getByText('Test')).toBeTruthy();
  });

  it('should move todo to completed on click', async () => {
    const onComplete = jest.fn();
    const todos = [{ id: 1, status: 'pending', title: 'Test' }];
    render(<TodoList todos={todos} onComplete={onComplete} />);

    fireEvent.click(screen.getByText('完成'));
    await waitFor(() => expect(onComplete).toHaveBeenCalledWith(1));
  });
});

验收标准:

  • 三状态Tab
  • 待办卡片
  • 状态切换
  • 批量操作
  • 筛选排序

Sprint 6: 完善与优化 (Days 34-40)

任务 6.1: 配置管理页面

时间: 1天 依赖: Sprint 5 验收标准:

  • OCR提供商配置
  • AI提供商配置
  • 配置测试功能

任务 6.2: 待处理图片页面

时间: 1天 依赖: Sprint 5 验收标准:

  • 待处理图片列表
  • 手动创建对话框
  • 图片增强功能

任务 6.3: 性能优化

时间: 1.5天 依赖: 所有Sprint 验收标准:

  • 前端代码分割
  • 图片懒加载
  • API响应缓存
  • 数据库查询优化

任务 6.4: 测试完善

时间: 1天 依赖: 所有Sprint 验收标准:

  • E2E测试补充
  • 覆盖率达到80%+
  • 所有测试通过

任务 6.5: 文档与部署

时间: 1.5天 依赖: 所有Sprint 验收标准:

  • API文档
  • 部署文档
  • Docker镜像构建
  • 一键部署验证

测试矩阵

Sprint 单元测试 集成测试 E2E测试 覆盖率目标
Sprint 1 20 5 0 80%
Sprint 2 35 10 3 80%
Sprint 3 40 8 2 80%
Sprint 4 30 8 4 85%
Sprint 5 25 5 8 75%
Sprint 6 7 0 2 80%
总计 157 36 19 80%

技术栈

测试框架

  • 后端单元: Jest
  • 后端集成: Supertest
  • 前端单元: Vitest
  • 前端组件: Testing Library
  • E2E: Playwright

代码质量工具

  • Linter: ESLint
  • Formatter: Prettier
  • Type Check: TypeScript
  • Coverage: c8 / istanbul

每日流程

开发开始

# 1. 拉取最新代码
git pull

# 2. 运行所有测试确保通过
npm test

# 3. 查看任务列表
# @ralph 我今天要做什么?

TDD 开发循环

# 1. 🔴 Red: 写失败的测试
# 创建测试文件,描述期望行为

# 2. 🟢 Green: 写最小代码通过
# 实现功能,不考虑代码质量

# 3. 🔵 Blue: 重构优化
# 清理代码,提取抽象

# 4. 提交代码
git add .
git commit -m "feat: description"

开发结束

# 1. 运行所有测试
npm test

# 2. 检查覆盖率
npm run test:coverage

# 3. 提交代码
git push

# 4. @ralph 今天我学到了什么?

Ralph Loop 检查清单

实现前

  • @ralph 我是否完全理解了要实现的功能?
  • @ralph 有什么边界情况我没考虑到?
  • @ralph 这个设计是否遵循 SOLID 原则?
  • @ralph 是否有更简单的实现方式?

实现中

  • @ralph 这段代码是否容易理解?
  • @ralph 变量/函数名是否清晰?
  • @ralph 是否有重复代码?
  • @ralph 这段代码性能如何?

实现后

  • @ralph 所有测试都通过了吗?
  • @ralph 代码可以更简洁吗?
  • @ralph 是否需要添加文档?
  • @ralph 我从这次实现中学到了什么?

风险和缓解

风险 影响 概率 缓解措施
AI API不稳定 测试失败 使用Mock减少真实调用
OCR耗时 测试慢 使用预设结果
时间估算偏差 延期 预留20%缓冲时间
需求变更 返工 快速反馈,小步迭代

成功指标

质量指标

  • 代码覆盖率: ≥ 80%
  • 测试通过率: 100%
  • TypeScript错误: 0
  • ESLint错误: 0

流程指标

  • 每日提交次数: ≥ 5
  • 代码审查时间: < 24小时
  • Bug修复时间: < 4小时

下一步

开发计划已制定完成。下一步:

  1. 查看Sprint详细计划 - 每个Sprint的具体任务
  2. 生成测试骨架 - 创建测试文件模板
  3. 开始开发 - 执行第一个TDD循环
# 查看Sprint 1详细计划
cat .project/sprints/sprint-1.md

# 开始开发
cd backend && npm test