docs: 完成治理文档与执行合同收口(A1-A2,R1-R2,S1-S2,P9A1-P9D1)
这个提交包含在:
@@ -0,0 +1,60 @@
|
||||
# ADR: 企业卡/虚拟卡管控能力预研
|
||||
|
||||
- **状态**: Accepted (PoC 完成)
|
||||
- **日期**: 2026-02-10
|
||||
- **关联 Issue**: S1
|
||||
|
||||
## 背景
|
||||
当前报销流程为“事后报销”。随着费用规模增长,管理层希望评估“企业卡/虚拟卡”是否值得投入,以降低垫资与票据补录成本,并与预算控制联动。
|
||||
|
||||
## 决策目标
|
||||
1. 明确能力边界(做什么/不做什么)。
|
||||
2. 给出最小可实施数据模型草案。
|
||||
3. 评估与预算控制联动价值与 ROI。
|
||||
4. 提供可回滚路径。
|
||||
|
||||
## 方案对比
|
||||
### 方案 A:不做企业卡,持续优化现有报销
|
||||
- 优点:实现成本最低,不引入支付清结算风险。
|
||||
- 缺点:员工垫资与票据补录问题长期存在。
|
||||
|
||||
### 方案 B:只做“虚拟卡授权 + 交易对账导入”(推荐)
|
||||
- 优点:
|
||||
- 可在现有 `integration_outbox` + `travel_orders` 机制上增量扩展。
|
||||
- 与预算池可形成“事前授权 + 事后核销”闭环。
|
||||
- 不直接改造核心审批状态机,风险可控。
|
||||
- 缺点:需要第三方支付/发卡通道,需处理对账延迟与异常交易。
|
||||
|
||||
### 方案 C:自建完整企业卡账务系统
|
||||
- 优点:掌控力最强。
|
||||
- 缺点:投入和合规成本过高,不符合当前阶段。
|
||||
|
||||
## PoC 结论
|
||||
- 使用 mock 交易流水模型验证:
|
||||
- 交易导入 -> 预算池扣减 -> 报销关联核销 可形成闭环。
|
||||
- 交易失败/重复导入可通过幂等键控制。
|
||||
- 关键风险:
|
||||
- 外部支付通道 SLA 不稳定;
|
||||
- 对账日切与本地时区差异;
|
||||
- 退款/撤销的反向台账一致性。
|
||||
|
||||
## 推荐落地范围(P8+)
|
||||
1. 新增 `card_transactions`(最小字段:external_txn_id、employee_id、amount、currency、occurred_at、status、raw_payload)。
|
||||
2. 新增 `card_authorizations`(预算池授权额度快照)。
|
||||
3. 与预算台账联动:
|
||||
- 授权占用 `kind=authorize`
|
||||
- 核销 `kind=settle`
|
||||
- 撤销 `kind=reverse`
|
||||
4. 不在首期引入自动拒付策略,仅做预警与冻结建议。
|
||||
|
||||
## ROI 粗评估
|
||||
- 假设月均 3000 笔差旅相关支出:
|
||||
- 票据补录和对账人工可减少约 30%~45%。
|
||||
- 财务月结周期可缩短约 1~2 天。
|
||||
- 若企业卡通道费率高于节省人工成本,建议暂缓。
|
||||
|
||||
## 回滚策略
|
||||
1. 关闭企业卡开关(保留历史数据)。
|
||||
2. 停止交易导入任务与对外同步。
|
||||
3. 预算恢复到“报销提交时校验”模式。
|
||||
4. 历史交易只读归档,不做数据删除。
|
||||
@@ -0,0 +1,58 @@
|
||||
# ADR: 移动端路线决策(PWA vs RN vs 小程序)
|
||||
|
||||
- **状态**: Accepted (PoC 完成)
|
||||
- **日期**: 2026-02-10
|
||||
- **关联 Issue**: S2
|
||||
|
||||
## 背景
|
||||
当前系统为响应式 Web。业务关注移动场景下的“离线拍照、弱网上传、回填状态可追踪”。
|
||||
|
||||
## 决策目标
|
||||
1. 选择下一阶段移动路线。
|
||||
2. 验证离线拍照与上传可靠性。
|
||||
3. 输出成本、风险、回滚方案。
|
||||
|
||||
## 备选方案
|
||||
### 方案 A:PWA(推荐)
|
||||
- 优点:
|
||||
- 基于现有 React/Vite 体系,团队学习成本低。
|
||||
- 可快速实现离线草稿、上传重试队列、安装到桌面。
|
||||
- 与现有鉴权与 API 契约兼容。
|
||||
- 缺点:
|
||||
- iOS 对后台同步和离线能力有限制。
|
||||
|
||||
### 方案 B:React Native
|
||||
- 优点:
|
||||
- 原生能力强,上传/相机/本地缓存控制更细。
|
||||
- 缺点:
|
||||
- 双端构建链路与发布流程显著增加。
|
||||
- 需要新增移动端测试与运维能力。
|
||||
|
||||
### 方案 C:微信/钉钉小程序
|
||||
- 优点:
|
||||
- 企业内推广成本低,触达快。
|
||||
- 缺点:
|
||||
- 生态绑定强,跨平台复用差。
|
||||
- 审核与平台能力限制较多。
|
||||
|
||||
## PoC 结果
|
||||
- PWA 原型验证:
|
||||
- 离线缓存拍照元数据可行;
|
||||
- 网络恢复后自动上传成功率高;
|
||||
- 异常重试与失败提示可在现有前端框架中快速实现。
|
||||
- RN 原型验证:
|
||||
- 能力更强,但初期投入约为 PWA 的 2~3 倍。
|
||||
|
||||
## 决策
|
||||
- **主路线**:PWA 优先。
|
||||
- **触发升级条件**:当离线强需求占比持续提升,且 PWA 在 iOS 场景无法满足 SLA 时,再升级 RN。
|
||||
|
||||
## 分阶段实施建议
|
||||
1. P7:补离线草稿与上传队列(仅票据上传)。
|
||||
2. P8:补断点续传、失败重放、可观测埋点。
|
||||
3. P9:基于指标评估是否进入 RN 立项。
|
||||
|
||||
## 回滚策略
|
||||
1. 保留 Web 主站能力,PWA 特性可通过开关关闭。
|
||||
2. 关闭 Service Worker 后回退到纯在线模式。
|
||||
3. 离线缓存可按版本清理,不影响服务端数据。
|
||||
+11
-3
@@ -141,9 +141,17 @@
|
||||
- CI 通过:typecheck + lint + 最小集成测试 + 脱敏测试全绿
|
||||
|
||||
## 3. Phase 2(扩展)
|
||||
- OCR、企微/钉钉通知、报表导出
|
||||
- 对象存储(MinIO/OSS)
|
||||
- 工作流扩展到其他实体(请假/采购)
|
||||
|
||||
> 状态口径说明(2026-02-09):
|
||||
> - 已落地:OCR 增强、报表导出、对象存储(MinIO/OSS)、工作流扩展到其他实体(最小骨架)。
|
||||
> - 待推进:企微/钉钉通知(渠道扩展)。
|
||||
> - 详细状态与证据以 `docs/feature-matrix.md` 与 `issues/2026-02-09_13-39-02-p5-blueprint-v3.csv` 为准。
|
||||
|
||||
- [x] OCR 能力增强(队列化与重试策略)
|
||||
- [ ] 企微/钉钉通知
|
||||
- [x] 报表导出
|
||||
- [x] 对象存储(MinIO/OSS)
|
||||
- [x] 工作流扩展到其他实体(请假/采购)
|
||||
|
||||
## 4. 风险与阻塞项(P0)
|
||||
- 财务对“费用类型/科目默认值”仍可能需要微调:通过 `expense_types` 配置解决,避免改代码
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# invoicePool 路由拆分方案(P9A1)
|
||||
|
||||
## 1. 背景
|
||||
- 现状:`server/src/routes/invoicePool.js` 超过 2700 行,上传、列表、详情、验真、归档、解绑、OCR 重试等职责集中在单文件。
|
||||
- 风险:
|
||||
- 验真链路迭代时容易与票据主流程互相影响。
|
||||
- `select` 片段与响应映射逻辑重复,字段漂移不易发现。
|
||||
- 新人接手定位成本高,回归面过大。
|
||||
|
||||
## 2. 目标与非目标
|
||||
- 目标:
|
||||
- 不改变现有 API 路径、权限码、响应结构。
|
||||
- 将验真端点独立到子模块,主文件保留入口职责。
|
||||
- 抽取 shared `select`/`mapper`,降低重复与字段遗漏风险。
|
||||
- 非目标:
|
||||
- 不新增业务功能。
|
||||
- 不调整数据库模型与外部接口契约。
|
||||
|
||||
## 3. 拆分边界冻结
|
||||
|
||||
### 3.1 保留在 `invoicePool.js` 的能力
|
||||
- 票据列表、上传、详情、编辑、归档、解绑、OCR 重试、判重例外、签名 URL 与文件读取。
|
||||
- 入口职责:对外仍由 `server/src/routes/invoicePool.js` 注册全部 `/api/invoice-pool/*` 路径。
|
||||
|
||||
### 3.2 独立模块
|
||||
- `server/src/routes/invoicePool/verification.js`
|
||||
- `POST /invoice-pool/:id/verify`
|
||||
- `GET /invoice-pool/:id/verification`
|
||||
- `POST /invoice-pool/:id/verification/retry`
|
||||
|
||||
### 3.3 shared 模块
|
||||
- `server/src/routes/invoicePool/shared/selects.js`
|
||||
- 统一 `verification_records` 子查询。
|
||||
- 提供列表/详情 `select` builder。
|
||||
- `server/src/routes/invoicePool/shared/mappers.js`
|
||||
- `mapVerificationRecord`
|
||||
- `mapInvoiceSummary`
|
||||
- `normalizeInvoiceResponse`
|
||||
- `server/src/routes/invoicePool/shared/schemas.js`
|
||||
- 验真列表查询参数解析。
|
||||
- `server/src/routes/invoicePool/shared/helpers.js`
|
||||
- 验真任务触发(`pg-boss`/inline 兼容)。
|
||||
|
||||
## 4. 迁移顺序
|
||||
1. 新增 shared 模块与 `verification.js`,逻辑先保持等价迁移。
|
||||
2. `invoicePool.js` 改为组合注册(调用 `verification.js`),删除内联验真端点。
|
||||
3. 将列表与详情相关查询切换到 shared `select` builder。
|
||||
4. 执行静态检查与验真回归脚本,确认无接口行为变化。
|
||||
|
||||
## 5. 兼容性与回滚
|
||||
- 兼容性:
|
||||
- 路由路径、权限码、返回字段保持不变。
|
||||
- 错误码(`VALID_001`/`PERM_001`/`SYS_404`)保持原语义。
|
||||
- 回滚策略:
|
||||
- 保留 `invoicePool.js` 入口文件与原有注册顺序。
|
||||
- 如发现回归,可将 `verification.js` 调用回切为原文件内联实现(无 schema 变更,无数据回滚)。
|
||||
|
||||
@@ -1067,25 +1067,29 @@ erDiagram
|
||||
|
||||
## 16. 迭代计划
|
||||
|
||||
> 状态口径说明(2026-02-09):
|
||||
> - 以 `issues/2026-02-09_13-39-02-p5-blueprint-v3.csv` 与 `docs/feature-matrix.md` 为实现状态事实源。
|
||||
> - 本节清单用于规格分期表达;具体执行状态以 Issue CSV 与实现状态矩阵为准。
|
||||
|
||||
### Phase 1(核心 / P0)
|
||||
- [x] 技术栈确定(Fastify + Prisma + PostgreSQL)
|
||||
- [ ] 员工与组织(含归档约束、角色集合)
|
||||
- [ ] 权限码体系与服务端校验(RBAC)
|
||||
- [ ] 工作流引擎(4 表)落库与服务层事务
|
||||
- [ ] `approval_rules`(预置 3 条)+ 审批链生效
|
||||
- [ ] 转审(reason≥10,链路≤3)
|
||||
- [ ] `document_sequences` 单号规则(BX-YYYYMMDD-0001)
|
||||
- [ ] 费用类型 `expense_types`(默认启用 37 项)+ 下拉动态加载
|
||||
- [ ] 发票池上传(本地存储 + 签名 URL)+ SHA256 + 腾讯云 OCR(结果持久化/去重/重试;不阻塞提交)+ 双策略判重(bind/submit 生效)+ 例外审计
|
||||
- [ ] 报销单 CRUD + 提交/撤回/审批/付款标记
|
||||
- [ ] 站内通知 + 邮件
|
||||
- [x] 员工与组织(含归档约束、角色集合)
|
||||
- [x] 权限码体系与服务端校验(RBAC)
|
||||
- [x] 工作流引擎(4 表)落库与服务层事务
|
||||
- [x] `approval_rules`(预置 3 条)+ 审批链生效
|
||||
- [x] 转审(reason≥10,链路≤3)
|
||||
- [x] `document_sequences` 单号规则(BX-YYYYMMDD-0001)
|
||||
- [x] 费用类型 `expense_types`(默认启用 37 项)+ 下拉动态加载
|
||||
- [x] 发票池上传(本地存储 + 签名 URL)+ SHA256 + 腾讯云 OCR(结果持久化/去重/重试;不阻塞提交)+ 双策略判重(bind/submit 生效)+ 例外审计
|
||||
- [x] 报销单 CRUD + 提交/撤回/审批/付款标记
|
||||
- [x] 站内通知 + 邮件
|
||||
|
||||
### Phase 2(扩展 / P1-P2)
|
||||
- [ ] OCR 能力增强(更多票种/批量处理/队列与更完整的失败重试策略)
|
||||
- [x] OCR 能力增强(更多票种/批量处理/队列与更完整的失败重试策略)
|
||||
- [ ] 企微/钉钉通知
|
||||
- [ ] 报表导出
|
||||
- [ ] 对象存储(MinIO/OSS)
|
||||
- [ ] 工作流扩展到其他实体(请假/采购等)
|
||||
- [x] 报表导出
|
||||
- [x] 对象存储(MinIO/OSS)
|
||||
- [x] 工作流扩展到其他实体(请假/采购等)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# 历史 TODO 清账映射(A/C -> E/F)
|
||||
|
||||
**日期**:2026-02-09
|
||||
**范围**:
|
||||
- `issues/2026-02-07-p2-kickoff.csv`
|
||||
- `issues/2026-02-08_14-20-25-p2-ci-and-tests.csv`
|
||||
|
||||
**目标**:对历史 `TODO` 项逐条给出去向:`implemented | superseded | still-open`。
|
||||
|
||||
## 1. 2026-02-07-p2-kickoff.csv
|
||||
|
||||
| Legacy ID | 标题 | 清账状态 | 对应实现 / 去向证据 |
|
||||
| --- | --- | --- | --- |
|
||||
| A1 | 付款凭证扩展与pay幂等冲突判定 | implemented | `issues/2026-02-08_11-02-30-p2-stabilization.csv:B1`(DONE);`server/src/routes/reimbursements.js` 含 `already_paid_conflict` 与 `idempotent` 处理 |
|
||||
| A2 | 委派有效期与自动回收 | implemented | `issues/2026-02-08_11-02-30-p2-stabilization.csv:B2/B3`(DONE);`server/src/routes/delegations.js` 与 `server/src/jobs/delegationRevokeJob.js` |
|
||||
| A5 | Sprint1回归护栏前置 | superseded | 由后续全量回归接管:`server/scripts/regression-workflow-actions.sh`、`server/scripts/regression-all.sh` 持续演进,见 `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D12` |
|
||||
| A3 | OCR真对接与异步处理 | implemented | `issues/2026-02-09_13-39-02-p5-blueprint-v3.csv:F11/F19b`(DONE);`server/src/services/ocr/tencent.js` 与 `server/src/jobs/pgBossJobs.js` |
|
||||
| A3-LOCK | OCR多实例并发幂等锁 | implemented | `issues/2026-02-09_13-39-02-p5-blueprint-v3.csv:F19b`(DONE);`server/src/jobs/ocrJob.js`(并发认领) |
|
||||
| A4 | 审计工作台只读能力 | implemented | `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D2`(DONE)+ `issues/2026-02-08_21-50-09-p4-trialrun-ready.csv`(前端页完善);`server/src/routes/audit.js` 与 `client/src/pages/AuditLogsPage.tsx` |
|
||||
|
||||
## 2. 2026-02-08_14-20-25-p2-ci-and-tests.csv
|
||||
|
||||
| Legacy ID | 标题 | 清账状态 | 对应实现 / 去向证据 |
|
||||
| --- | --- | --- | --- |
|
||||
| C2 | 审计接口自动化测试 | implemented | `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D2`(DONE);`server/scripts/regression-audit.sh` |
|
||||
| C3 | OCR 自动化测试(Mock优先) | implemented | `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D3`(DONE);`server/scripts/regression-ocr.sh` |
|
||||
| C4 | P3-a 待办列表页落地 | implemented | `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D6`(DONE);`client/src/pages/WorkflowTasksPage.tsx` |
|
||||
| C5 | P3-a 审批详情与动作联调 | implemented | `issues/2026-02-08_17-05-00-p3-full-delivery.csv:D6`(DONE);`client/src/pages/WorkflowTaskDetailPage.tsx` |
|
||||
|
||||
## 3. 汇总结论
|
||||
|
||||
- `implemented`:9
|
||||
- `superseded`:1
|
||||
- `still-open`:0
|
||||
|
||||
> 说明:历史 CSV 快照保持不改;清账通过该文档形成可审计映射链。
|
||||
在新工单中引用
屏蔽一个用户