# 技术决策记录 (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; suggestTags(content: string): Promise; suggestCategory(content: string, categories: string[]): Promise; extractTodos(content: string): Promise; } ``` ### 影响 - 增加抽象层开发成本 - 长期维护成本降低 - 便于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 | 新增 | 异步任务处理 |