06 - 里程碑与排期(Web SaaS)¶
本路线图以 03-architecture.md 的 Web SaaS 架构和 04-database.md 的工作区模型为前提。旧 Python/SQLite 桌面版已从主仓库移除;领域逻辑和测试迁移至 TypeScript monorepo。
每个里程碑结束时都必须通过 pnpm lint、pnpm typecheck、pnpm test 与 pnpm build。涉及 schema 的任务还必须验证 Prisma migration 能在空库部署,并覆盖 RLS 隔离测试。
Milestone 0:平台与数据边界(1 周)¶
目标:建立可部署、可登录、不会跨用户泄露数据的最小底座。没有这一层,不进入 OCR 或上传功能开发。
| # | 任务 | 产出 | 依赖 |
|---|---|---|---|
| 1 | 创建 pnpm workspace、Turborepo、web/api/worker/packages 骨架 | Monorepo、共享 lint/typecheck/test 配置、Dockerfile | — |
| 2 | Docker Compose:web、api、worker、PostgreSQL、Redis 与 /data 卷(Caddy 反代在宿主机) |
内网单机启动、healthz、SSE 即时 flush | 1 |
| 3 | Prisma + better-auth | user/session/account/verification、用户名登录、首个 admin 初始化、会话集成测试 |
1, 2 |
| 4 | 工作区基础模型 | organization、成员、个人工作区自动创建、工作区选择器与 X-Workspace-Id 校验 |
3 |
| 5 | 数据安全底座 | RLS、workspace_id 复合外键、access_audit、信封加密服务、脱敏日志 |
4 |
| 6 | 文件存储抽象 | file_blob/workspace_file、受控下载端点、本地 /data/invoice/{workspace_id}/ 实现 |
4, 5 |
验收标准:两个普通用户和一个管理员登录后,仅能看到各自个人工作区;伪造 X-Workspace-Id、跨工作区资源 ID、raw SQL 查询均无法越权。管理员排障访问产生审计记录。服务重启后 session、数据库和挂载卷数据保持可用。
Milestone 1:个人工作区报销闭环(2~3 周)¶
目标:在个人工作区完成“上传 → OCR → 分类 → 归档 → 查看”的可用闭环,保留所有关键领域红线。
| # | 任务 | 产出 | 依赖 |
|---|---|---|---|
| 1 | 上传与任务 API | multipart 校验、原子落盘、workspace_file 防重、parse_task 入队、任务查询 |
M0 |
| 2 | BullMQ 解析 worker | 并发 2 + 2 QPS 限速、30s/2m/10m 退避、stalled 与启动补偿 | 1 |
| 3 | 百度 Provider 移植 | token、OCR 调用、金额转分、日期清洗、完整原始 JSON 留存、responses/fixture 测试平移 | 2 |
| 4 | 组织级发票防重 | invoice_dedup_key 事务争抢、全电票空代码兼容、跨空间无信息泄露提示 |
3 |
| 5 | 规则与归档领域逻辑 | 分类器链契约 + 规则组实现(用户/工作区/组织规则 → 内置科目词典 taxonomy:default → ServiceType 直映别名归一 → 未分类)+ category_source 溯源;归档纯写库(虚拟路径固化)、同前缀命名纯函数 |
3 |
| 6 | Web 主工作台 | 登录保护、工作区上下文、上传区、任务卡片、发票表格、详情与字段修正 | 1, 3, 5 |
| 7 | SSE 与站内通知 | 任务状态、发票创建、统计刷新、通知未读状态;断线补拉 | 2, 6 |
验收标准:同一工作区连续上传 20 个混合文件(重复文件、重复票号、损坏文件均包含),不会超过 OCR QPS;正确发票归档、失败任务可重试、重复票不泄露其他空间信息。浏览器刷新与 worker 重启后任务和文件最终收敛。
Milestone 2:协作、附件与报销输出(2~3 周)¶
目标:让共享工作区能够安全协作,并交付完整报销材料。
| # | 任务 | 产出 | 依赖 |
|---|---|---|---|
| 1 | 共享工作区与成员管理 | 创建/归档共享空间、邀请和移除成员、角色能力校验、成员变更立即失权 | M0 |
| 2 | 附件子管道 | 282103 转通用 OCR、全文与匹配信号保存、反查补挂、待配对页面与人工配对 | M1 |
| 3 | 批次管理 | 建批、入批、拆批、排序、状态流转、报销类型与按类型自动分流、archive_path 前缀更新(纯写库);跨工作区入批必须失败 | M1, 2 |
| 4 | Excel 与 PDF 导出 | ExcelJS 模板填充、pdf-lib 合并、异步 export job、受控下载、批次目录落盘 | 3 |
| 5 | 邮箱账户与 IMAP worker | 信封加密凭据、测试连接、筛选、水位/Message-ID 防重、手动触发和 cron 拉取 | M1 |
| 6 | Webhook 通知 | 钉钉、飞书、通用 Webhook、权限控制、签名、聚合降噪、测试发送 | M1 |
| 7 | 协作与导出 UI | 成员管理、附件待配对、批次排序/导出、邮箱账户与频道设置页 | 1–6 |
| 8 | 结构化财务票据识别 | 财务端点注册表、网约车行程单结构化(城市/起终点/每段金额)、票种归类与专属字段、发票库「城市-起点-终点」命名(docs/12) | 2 |
验收标准:共享空间成员能看到同一批次与材料,未加入者无法通过 API、下载 URL 或 SSE 获得信息;主票迁移时附件随行。Excel、PDF 与批次文件均只能由该工作区成员下载。邮箱重复拉取不重复消耗 OCR 配额。
Milestone 3:额度与报销效率增强(1~2 周)¶
目标:在稳定的工作区模型上增加额度管理和半自动操作,不改变人工最终提交的边界。
| # | 任务 | 产出 | 依赖 |
| --- | --- | --- |
| 1 | 手动额度计划与统计 | 个人/共享额度、周期聚合、仪表盘剩余、超限提示 | M2 |
| 2 | 智能组单 | 按额度剩余的子集和建议、出差时间窗口建议;结果仅供用户确认 | 1 |
| 3 | OA 额度快照 | Ego-lite 抓取余额、quota_snapshot、本地与 OA 偏差预警 | 1 |
| 4 | OA 半自动填报 | 填写和上传自动化,提交前强制人工确认;失败可回到批次继续处理 | M2 |
| 5 | 旧数据一次性导入 | SQLite 工作区导入指定个人/共享工作区,文件入 blob 层换算虚拟路径,重复票冲突报告 | M2 |
| 6 | 运维收尾 | pg_dump 与 /data 快照、加密主密钥交接与恢复演练、性能压测 | M0–M2 |
| 7 | 模型判别分类器 | LLM/ML 环实现分类器契约,兜底规则未分类;按 category_source 对比评估与全量重放 | M1 任务 5 契约 |
| 8 | 平台用量计量与配额 | OCR/决策模型调用计量(call/token、成本)、组织级配额预检与 /usage API;缓存命中不计费 | M2 |
| 9 | 管理大屏 | 系统管理员全局只读大屏:用户/租户、各 API 用量与成本、各功能使用;/admin/dashboard + 零依赖 SVG 前端 | 8 |
验收标准:额度金额全程以分计算;OA 自动化永不自动提交;导入后原件、附件、批次和 OCR 原始数据可追溯;能从备份恢复数据库、文件和凭据解密能力。
后续候选项(未排期)¶
- 完整审批流、成本中心与预算分摊。
- CAS/LDAP/OIDC 正式接入与用户目录同步。
- MinIO/S3 文件存储实现、多机部署与高可用。
- 公有云多组织运营、自助注册与计费。
这些项涉及新的产品政策和权限边界,启动前需先补充 PRD,不以当前工作区模型的“自然延伸”默认实现。
风险跟踪¶
| 风险 | 等级 | 缓解 |
|---|---|---|
| 多用户越权或文件直出 | 高 | M0 前置 RLS、复合外键、受控下载、跨空间集成测试与审计日志。 |
| 百度 OCR 出站受限/限流 | 高 | HTTP_PROXY、BullMQ 2 QPS 限速、退避重试、任务可重放。 |
| 加密主密钥丢失 | 高 | 部署交接保管、备份恢复演练;后续支持双密钥轮换。 |
| better-auth schema 升级漂移 | 中 | 锁定版本,generate → Prisma Migrate 与登录/会话/角色集成测试。 |
| 邮箱服务兼容性与授权码过期 | 中 | 测试连接、掩码回显、last_error、连续失败计数(不发通知)、UID + Message-ID 防重。 |
| Webhook 限频或失败 | 中 | 站内通知兜底、聚合窗口、发送间隔、错误状态可见。 |
| OA 页面改版 | 中 | 半自动、选择器配置化;抓取失败降级为手动额度。 |
| Excel/PDF 与现有模板不符 | 中 | M2 使用真实模板做验收,模板可替换,必要时增加像素级回归。 |