完整的前后端图片分析应用,包含: - 后端: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>
389 lines
8.3 KiB
Markdown
389 lines
8.3 KiB
Markdown
# 技术决策记录 (ADR)
|
||
|
||
## 项目信息
|
||
- **项目名称**: 图片OCR与智能文档管理系统
|
||
- **记录时间**: 2026-02-21
|
||
- **记录人**: 架构师
|
||
|
||
---
|
||
|
||
## ADR-001: 前端框架选择
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
需要选择一个前端框架来构建Web UI,要求:组件丰富、开发效率高、适合中小型项目。
|
||
|
||
### 决策
|
||
使用 **React 18** 作为前端框架
|
||
|
||
### 理由
|
||
| 优势 | 说明 |
|
||
|------|------|
|
||
| 生态成熟 | 组件库、工具链丰富 |
|
||
| Ant Design | 企业级UI组件库,减少开发量 |
|
||
| 开发者熟悉 | 团队React经验丰富 |
|
||
| 社区支持 | 问题解决成本低 |
|
||
|
||
### 考虑过的方案
|
||
- **Vue 3**: 也很优秀,但Ant Design React更适合本项目
|
||
- **Svelte**: 生态相对较小,不如React成熟
|
||
|
||
### 影响
|
||
- 技术栈统一为React生态
|
||
- 使用Vite作为构建工具
|
||
- 使用Zustand/React Query管理状态
|
||
|
||
---
|
||
|
||
## ADR-002: 后端框架选择
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
需要选择Node.js后端框架,要求:轻量、灵活、中间件丰富。
|
||
|
||
### 决策
|
||
使用 **Express.js** 作为后端框架
|
||
|
||
### 理由
|
||
| 优势 | 说明 |
|
||
|------|------|
|
||
| 成熟稳定 | 生产环境验证充分 |
|
||
| 中间件丰富 | 认证、日志、CORS等开箱即用 |
|
||
| 灵活性高 | 不强制架构,便于定制 |
|
||
| 学习成本低 | 团队熟悉度高 |
|
||
|
||
### 考虑过的方案
|
||
- **Fastify**: 性能更好,但生态不如Express
|
||
- **Koa**: 更现代,但中间件模式不同,迁移成本
|
||
|
||
### 影响
|
||
- 使用Express Router组织API
|
||
- 使用JWT认证
|
||
- 使用Prisma ORM
|
||
|
||
---
|
||
|
||
## ADR-003: 数据库选择
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
项目规模为个人/小团队,需要平衡开发效率和可扩展性。
|
||
|
||
### 决策
|
||
开发环境使用 **SQLite**,生产环境可切换到 **PostgreSQL**
|
||
|
||
### 理由
|
||
| SQLite优势 | PostgreSQL优势 |
|
||
|------------|----------------|
|
||
| 零配置部署 | 支持更高并发 |
|
||
| 开发便利 | 全文搜索更好 |
|
||
| 备份简单 | JSON类型支持 |
|
||
| 适合原型 | 生产级可靠性 |
|
||
|
||
### 考虑过的方案
|
||
- **MySQL**: 与PostgreSQL类似,但JSON支持较弱
|
||
- **MongoDB**: 不需要文档数据库的灵活性
|
||
- **纯文件存储**: 不支持复杂查询
|
||
|
||
### 影响
|
||
- 使用Prisma ORM,便于切换数据库
|
||
- 开发阶段使用SQLite简化流程
|
||
- 生产环境通过环境变量切换
|
||
|
||
---
|
||
|
||
## ADR-004: OCR方案架构
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
用户对OCR有不同需求(隐私、成本、速度),需要灵活支持。
|
||
|
||
### 决策
|
||
采用 **可配置的OCR插件架构**,支持本地和云端两种模式
|
||
|
||
### 理由
|
||
| 方案 | 优势 | 劣势 |
|
||
|------|------|------|
|
||
| 本地OCR | 隐私好、无持续成本 | 需要GPU、速度慢 |
|
||
| 云端API | 准确率高、快速 | 持续费用、隐私顾虑 |
|
||
|
||
### 实现方案
|
||
```
|
||
OCRProvider (Interface)
|
||
├── LocalOCREngine (PaddleOCR)
|
||
├── BaiduOCREngine
|
||
├── TencentOCREngine
|
||
└── AliyunOCREngine
|
||
```
|
||
|
||
### 影响
|
||
- 增加开发复杂度
|
||
- 需要统一的错误处理
|
||
- 用户可自由切换
|
||
|
||
---
|
||
|
||
## ADR-005: AI提供商集成方式
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
需要支持GLM、MiniMax、DeepSeek等多个AI提供商。
|
||
|
||
### 决策
|
||
使用 **统一的AI抽象层**,通过配置切换提供商
|
||
|
||
### 理由
|
||
- 避免代码与特定提供商耦合
|
||
- 便于添加新的AI服务
|
||
- 统一的错误处理和重试逻辑
|
||
- 统一的prompt管理
|
||
|
||
### 接口设计
|
||
```typescript
|
||
interface AIProvider {
|
||
name: string;
|
||
analyze(content: string, options?: AIOptions): Promise<AIResult>;
|
||
suggestTags(content: string): Promise<string[]>;
|
||
suggestCategory(content: string, categories: string[]): Promise<string>;
|
||
extractTodos(content: string): Promise<TodoItem[]>;
|
||
}
|
||
```
|
||
|
||
### 影响
|
||
- 增加抽象层开发成本
|
||
- 长期维护成本降低
|
||
- 便于A/B测试不同模型
|
||
|
||
---
|
||
|
||
## ADR-006: 前端状态管理方案
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
React项目需要状态管理,处理用户认证、文档列表、待办等状态。
|
||
|
||
### 决策
|
||
组合使用 **Zustand** (全局状态) 和 **React Query** (服务器状态)
|
||
|
||
### 理由
|
||
| Zustand优势 | React Query优势 |
|
||
|-------------|----------------|
|
||
| 轻量简洁 | 自动缓存/重新验证 |
|
||
| 无需Provider | 乐观更新 |
|
||
| TypeScript友好 | 请求去重 |
|
||
| 易于调试 | 后台数据同步 |
|
||
|
||
### 责任划分
|
||
- **Zustand**: UI状态(模态框、侧边栏、用户偏好)
|
||
- **React Query**: 服务器数据(文档、待办、分类)
|
||
|
||
### 影响
|
||
- 减少样板代码
|
||
- 自动处理加载和错误状态
|
||
- 更好的用户体验
|
||
|
||
---
|
||
|
||
## ADR-007: 文件存储方案
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
需要存储用户上传的图片文件,考虑成本、性能、扩展性。
|
||
|
||
### 决策
|
||
使用 **本地文件系统** 存储,支持未来扩展到OSS
|
||
|
||
### 理由
|
||
| 方案 | 适用场景 |
|
||
|------|----------|
|
||
| 本地存储 | 小规模、成本优先 |
|
||
| 阿里云OSS | 大规模、CDN加速 |
|
||
| AWS S3 | 国际化场景 |
|
||
|
||
### 实现策略
|
||
1. 基础版本使用本地存储
|
||
2. 抽象存储接口便于切换
|
||
3. 支持环境变量配置
|
||
|
||
### 目录结构
|
||
```
|
||
uploads/
|
||
├── images/
|
||
│ ├── {user_id}/
|
||
│ │ ├── {year}/{month}/
|
||
│ │ │ └── {uuid}.{ext}
|
||
```
|
||
|
||
### 影响
|
||
- Docker部署需要volume挂载
|
||
- 备份策略需要考虑文件
|
||
|
||
---
|
||
|
||
## ADR-008: 认证方案
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
多用户系统需要安全的身份认证机制。
|
||
|
||
### 决策
|
||
使用 **JWT (JSON Web Token)** 进行无状态认证
|
||
|
||
### 理由
|
||
| JWT优势 | 说明 |
|
||
|---------|------|
|
||
| 无状态 | 服务端不存储session |
|
||
| 跨域友好 | 适合前后端分离 |
|
||
| 性能好 | 无需数据库查询session |
|
||
| 标准化 | 生态工具完善 |
|
||
|
||
### 实现细节
|
||
- Access Token有效期: 24小时
|
||
- Refresh Token: 可选(未来扩展)
|
||
- 存储方式: httpOnly Cookie或localStorage
|
||
- 密码加密: bcrypt
|
||
|
||
### 安全措施
|
||
- HTTPS传输
|
||
- Token签名验证
|
||
- 密码强度要求
|
||
- 登录失败限制
|
||
|
||
---
|
||
|
||
## ADR-009: Docker部署策略
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
需要支持一键部署,简化用户使用门槛。
|
||
|
||
### 决策
|
||
使用 **Docker Compose** 编排多容器部署
|
||
|
||
### 容器划分
|
||
| 容器 | 职责 |
|
||
|------|------|
|
||
| frontend | React静态文件服务 |
|
||
| backend | Express API服务 |
|
||
| ocr-service | 本地OCR服务(可选) |
|
||
| nginx | 反向代理 |
|
||
|
||
### 理由
|
||
- 简化部署流程
|
||
- 环境一致性
|
||
- 易于扩展和升级
|
||
- 支持本地OCR服务隔离
|
||
|
||
### 影响
|
||
- 需要编写详细的部署文档
|
||
- 需要提供环境变量配置模板
|
||
|
||
---
|
||
|
||
## ADR-010: 异步任务处理
|
||
|
||
### 状态
|
||
已采纳 ✅
|
||
|
||
### 背景
|
||
OCR和AI分析都是耗时操作,不应阻塞用户请求。
|
||
|
||
### 决策
|
||
使用 **内存队列 + 轮询** 的方式处理异步任务
|
||
|
||
### 理由
|
||
| 方案 | 优势 | 劣势 |
|
||
|------|------|------|
|
||
| 内存队列 | 简单、无需额外服务 | 重启丢失 |
|
||
| Redis队列 | 持久化、分布式 | 额外依赖 |
|
||
| 消息队列 | 企业级 | 过于复杂 |
|
||
|
||
### 任务流程
|
||
```
|
||
1. 用户上传图片
|
||
2. 返回taskId
|
||
3. 后台异步处理
|
||
4. 前端轮询状态
|
||
5. 完成后获取结果
|
||
```
|
||
|
||
### 影响
|
||
- 前端需要实现轮询逻辑
|
||
- 任务状态需要持久化
|
||
- 考虑添加WebSocket优化(未来)
|
||
|
||
---
|
||
|
||
## 待决策项
|
||
|
||
| 编号 | 主题 | 计划决策时间 |
|
||
|------|------|--------------|
|
||
| ADR-011 | 日志方案 | Sprint 2 |
|
||
| ADR-012 | 监控告警 | Sprint 4 |
|
||
| ADR-013 | 备份策略 | Sprint 5 |
|
||
| ADR-014 | 前端路由模式 | Sprint 1 |
|
||
|
||
---
|
||
|
||
## 决策模板
|
||
|
||
```markdown
|
||
## ADR-XXX: 决策标题
|
||
|
||
### 状态
|
||
[提议中/已采纳/已废弃/已替代]
|
||
|
||
### 背景
|
||
[描述驱动这个决策的上下文]
|
||
|
||
### 决策
|
||
[我们做了什么决定]
|
||
|
||
### 理由
|
||
[为什么做出这个决定]
|
||
|
||
### 考虑过的方案
|
||
[我们考虑过哪些替代方案]
|
||
|
||
### 影响
|
||
[这个决策会产生什么影响]
|
||
|
||
### 相关决策
|
||
[关联的其他ADR]
|
||
```
|
||
|
||
---
|
||
|
||
## 变更历史
|
||
|
||
| 日期 | ADR编号 | 变更类型 | 说明 |
|
||
|------|---------|----------|------|
|
||
| 2026-02-21 | ADR-001 | 新增 | 前端框架选择 |
|
||
| 2026-02-21 | ADR-002 | 新增 | 后端框架选择 |
|
||
| 2026-02-21 | ADR-003 | 新增 | 数据库选择 |
|
||
| 2026-02-21 | ADR-004 | 新增 | OCR方案架构 |
|
||
| 2026-02-21 | ADR-005 | 新增 | AI提供商集成 |
|
||
| 2026-02-21 | ADR-006 | 新增 | 状态管理方案 |
|
||
| 2026-02-21 | ADR-007 | 新增 | 文件存储方案 |
|
||
| 2026-02-21 | ADR-008 | 新增 | 讴证方案 |
|
||
| 2026-02-21 | ADR-009 | 新增 | Docker部署 |
|
||
| 2026-02-21 | ADR-010 | 新增 | 异步任务处理 |
|