Files
PicAnalysis/.project/decisions.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

389 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 技术决策记录 (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 | 新增 | 异步任务处理 |