# 技术决策记录 (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 | 新增 | 异步任务处理 |
