From 3813d1955e13fbe28fbf642f177ddaaf6b70596d Mon Sep 17 00:00:00 2001 From: shunli Date: Tue, 10 Feb 2026 11:29:20 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=AE=8C=E6=88=90=E6=B2=BB=E7=90=86?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=B8=8E=E6=89=A7=E8=A1=8C=E5=90=88=E5=90=8C?= =?UTF-8?q?=E6=94=B6=E5=8F=A3=EF=BC=88A1-A2,R1-R2,S1-S2,P9A1-P9D1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/adr/adr-enterprise-card-control.md | 60 +++++++++++++++++++ docs/adr/adr-mobile-strategy.md | 58 ++++++++++++++++++ docs/implementation_plan.md | 14 ++++- docs/invoice-pool-refactor-plan.md | 57 ++++++++++++++++++ docs/requirements-specification.md | 32 +++++----- docs/todo-reconciliation.md | 36 +++++++++++ ...026-02-09_22-45-00-feature-matrix-docs.csv | 3 + ...9_23-30-00-p6-p8-remaining-work-master.csv | 21 +++++++ ...2-31-p9-maintenance-performance-matrix.csv | 9 +++ 9 files changed, 273 insertions(+), 17 deletions(-) create mode 100644 docs/adr/adr-enterprise-card-control.md create mode 100644 docs/adr/adr-mobile-strategy.md create mode 100644 docs/invoice-pool-refactor-plan.md create mode 100644 docs/todo-reconciliation.md create mode 100644 issues/2026-02-09_22-45-00-feature-matrix-docs.csv create mode 100644 issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv create mode 100644 issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv diff --git a/docs/adr/adr-enterprise-card-control.md b/docs/adr/adr-enterprise-card-control.md new file mode 100644 index 00000000..23ef2190 --- /dev/null +++ b/docs/adr/adr-enterprise-card-control.md @@ -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. 历史交易只读归档,不做数据删除。 diff --git a/docs/adr/adr-mobile-strategy.md b/docs/adr/adr-mobile-strategy.md new file mode 100644 index 00000000..52d20e67 --- /dev/null +++ b/docs/adr/adr-mobile-strategy.md @@ -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. 离线缓存可按版本清理,不影响服务端数据。 diff --git a/docs/implementation_plan.md b/docs/implementation_plan.md index f542d35a..fd6d9f3c 100644 --- a/docs/implementation_plan.md +++ b/docs/implementation_plan.md @@ -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` 配置解决,避免改代码 diff --git a/docs/invoice-pool-refactor-plan.md b/docs/invoice-pool-refactor-plan.md new file mode 100644 index 00000000..f180acc5 --- /dev/null +++ b/docs/invoice-pool-refactor-plan.md @@ -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 变更,无数据回滚)。 + diff --git a/docs/requirements-specification.md b/docs/requirements-specification.md index 3f76f8ee..c2bd102a 100644 --- a/docs/requirements-specification.md +++ b/docs/requirements-specification.md @@ -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] 工作流扩展到其他实体(请假/采购等) --- diff --git a/docs/todo-reconciliation.md b/docs/todo-reconciliation.md new file mode 100644 index 00000000..8cc5bb4b --- /dev/null +++ b/docs/todo-reconciliation.md @@ -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 快照保持不改;清账通过该文档形成可审计映射链。 diff --git a/issues/2026-02-09_22-45-00-feature-matrix-docs.csv b/issues/2026-02-09_22-45-00-feature-matrix-docs.csv new file mode 100644 index 00000000..db5e3e58 --- /dev/null +++ b/issues/2026-02-09_22-45-00-feature-matrix-docs.csv @@ -0,0 +1,3 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +A1,新增实现状态矩阵文档,新增 docs/feature-matrix.md,汇总 P5 v3 的 45 项功能(F1-F42 + F19b/F19c/F19d),包含规格章节、完成CSV、完成日期、状态与回归覆盖信息,文档存在且可渲染;矩阵覆盖45项且ID唯一;字段包含 ID/Title/Spec_Section/Planned_CSV/Done_CSV/Done_Date/Status/Regression_Coverage/Notes,manual: 对照 issues/2026-02-09_13-39-02-p5-blueprint-v3.csv 逐项核对ID与标题;检查矩阵总数=45,manual,DONE,DONE,DONE,docs/feature-matrix.md,[],none +A2,架构文档新增矩阵链接,在 docs/architecture.md 增加实现状态矩阵链接,明确 CSV 为执行合同、矩阵为全局读图,architecture 文档包含指向 docs/feature-matrix.md 的可点击链接;原有架构内容不被破坏,manual: 打开 docs/architecture.md 检查链接可见;复核 docs/feature-matrix.md 可访问,manual,DONE,DONE,DONE,docs/architecture.md,"[""A1""]",none diff --git a/issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv b/issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv new file mode 100644 index 00000000..dc255858 --- /dev/null +++ b/issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv @@ -0,0 +1,21 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +R1,历史TODO清账映射(A/C -> E/F),对 2026-02-07-p2-kickoff.csv 与 2026-02-08_14-20-25-p2-ci-and-tests.csv 的 TODO 项逐条映射到 implemented/superseded/still-open 并给出证据路径,历史 TODO 100% 有去向且可追溯到具体 CSV/代码路径,manual: 人工逐条对照旧 CSV 与最新 feature-matrix/blueprint-v3 并复核映射表,manual,DONE,DONE,DONE,docs/todo-reconciliation.md | issues/2026-02-07-p2-kickoff.csv | issues/2026-02-08_14-20-25-p2-ci-and-tests.csv,[],none +R2,规格与计划文档状态同步,修正 requirements-specification 与 implementation_plan 中与当前实现冲突的状态描述并补充引用 feature-matrix 的口径说明,两份文档状态与 feature-matrix 与 p5-blueprint-v3 一致且不改变业务语义,manual: 对照 docs/feature-matrix.md 与 issues/2026-02-09_13-39-02-p5-blueprint-v3.csv 复核文档状态项,manual,DONE,DONE,DONE,docs/requirements-specification.md | docs/implementation_plan.md,"[""R1""]",none +R3,状态一致性自动校验与CI接入,新增脚本校验 feature-matrix 与蓝图 CSV 的 ID/状态一致性并接入最小门禁,PR 执行 check-minimal 时可阻断矩阵漂移且输出可定位差异,cd /home/shunli/Projects/hyb-oa && ./scripts/check-minimal.sh,manual,DONE,DONE,DONE,scripts/validate-feature-matrix.py | scripts/check-minimal.sh | .github/workflows/ci-minimal.yml,"[""R2""]",none +V1,验真域模型与Provider抽象,新增 invoice_verification_records 模型与 provider 抽象(mock 与 tax 占位)且不破坏 OCR 流程,支持记录验真请求结果错误耗时请求人并可追溯到票据,cd server && npm run prisma:validate && node --check src/routes/invoicePool.js,manual,DONE,DONE,DONE,server/prisma/schema.prisma | server/src/services/verification/* | server/src/config.js,"[""R3""]",默认 INVOICE_VERIFICATION_ENABLED=false;provider 优先 mock +V2,验真API与异步任务(pg-boss),新增 verify/query/retry API 与 pg-boss 任务编排并写入审计日志,状态流转 pending->passed/failed/error 正确且重试频控可配置并可审计,manual: 启用 mock provider 后触发 verify 与 retry 并查询审计日志,manual,DONE,DONE,DONE,server/src/routes/invoicePool.js | server/src/jobs/pgBossJobs.js | server/src/jobs/jobSystem.js | server/src/routes/audit.js,"[""V1""]",none +V3,票据中心验真前端闭环,在 InvoicePoolPage 增加验真状态展示手动触发失败原因与权限控制,角色可见性正确状态与后端一致错误码文案可操作,cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/pages/InvoicePoolPage.tsx | client/src/api/invoicePool.ts | client/src/api/errorMessages.ts,"[""V2""]",none +V4,验真回归脚本与总回归接入,新增 regression-verification.sh 并通过环境变量接入 regression-all.sh,mock 模式可稳定跑通验真闭环且失败输出可定位,cd server && ./scripts/regression-verification.sh && RUN_VERIFICATION_REGRESSION=1 ./scripts/regression-all.sh,manual,DONE,DONE,DONE,server/scripts/regression-verification.sh | server/scripts/regression-all.sh | server/README.md,"[""V2"",""V3""]",none +D1,看板聚合API,新增费用总览趋势分类TopN审批效率聚合接口并支持时间与部门过滤,接口支持 dateFrom/dateTo/departmentId 且权限隔离正确,manual: 调用 dashboard API 校验过滤条件与权限边界,manual,DONE,DONE,DONE,server/src/routes/dashboard.js | server/src/app.js | server/src/constants/permissions.js,"[""R3""]",none +D2,前端Dashboard强化,在 DashboardPage 接入真实指标卡趋势图分类分布并支持 drill-down,角色可见性正确空态与错误态完整且性能可接受,cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/pages/DashboardPage.tsx | client/src/api/dashboard.ts,"[""D1""]",none +D3,看板导出联动,为看板统计增加 CSV/XLSX 导出并写审计,导出字段与页面过滤一致且审计可检索,manual: 调用 dashboard 导出并核对字段与审计动作,manual,DONE,DONE,DONE,server/src/routes/exports.js | client/src/pages/DashboardPage.tsx | client/src/api/exports.ts,"[""D1""]",复用现有 export 能力避免重复造轮子 +B1,预算池与台账模型,新增 budget_pools 与 budget_ledger_entries 模型含周期与预警阈值,支持 allocated/used/remaining 周期统计与审计字段,cd server && npm run prisma:validate,manual,DONE,DONE,DONE,server/prisma/schema.prisma | server/prisma/migrations/*,"[""R3""]",迁移仅 ADD TABLE/COLUMN/INDEX +B2,预算API与提交流程拦截,新增预算 CRUD 查询与 submit 校验并支持 warn/block 模式开关,超阈值行为符合 BUDGET_CONTROL_MODE 且审计完整,manual: 分别在 warn/block 下提交报销验证行为与审计,manual,DONE,DONE,DONE,server/src/routes/budgets.js | server/src/routes/reimbursements.js | server/src/config.js,"[""B1""]",默认 BUDGET_CONTROL_MODE=warn +B3,预算前端运营页,新增预算管理页面与提交前预算提示条,finance/manager 可运营员工可见必要告警且不影响既有提交流程,cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/pages/BudgetsPage.tsx | client/src/api/budgets.ts | client/src/pages/ReimbursementDetailPage.tsx,"[""B2""]",none +B4,预算回归脚本,新增 regression-budget.sh 覆盖 warn/block 两模式并可接入总回归,脚本可重复执行稳定且失败可定位,cd server && ./scripts/regression-budget.sh,manual,DONE,DONE,DONE,server/scripts/regression-budget.sh | server/scripts/regression-all.sh | server/README.md,"[""B2"",""B3""]",none +I1,集成框架(Outbox+Adapter),建立统一出站事件与适配器重试死信框架并提供审计,事件出站重试死信可观测且业务层不直接耦合第三方,manual: 触发一条出站事件并验证重试与审计,manual,DONE,DONE,DONE,server/prisma/schema.prisma | server/src/services/integrations/* | server/src/jobs/pgBossJobs.js,"[""R3""]",优先复用 pg-boss 不引入新队列 +I2,ERP最小集成(paid同步),实现 paid 报销同步 ERP 的最小适配器支持手动重推与幂等,paid 单据可同步失败可重试且可关闭回滚,manual: mock ERP 下触发同步与重推并验证幂等,manual,DONE,DONE,DONE,server/src/routes/integrations.js | server/src/services/integrations/erp/* | server/src/routes/reimbursements.js,"[""I1""]",默认 ERP_SYNC_ENABLED=false +I3,差旅单导入与报销关联,提供差旅订单导入接口与报销关联字段实现最小闭环,导入可幂等可关联可审计且失败不影响核心报销流,manual: 导入同一订单两次验证幂等并关联报销,manual,DONE,DONE,DONE,server/src/routes/travelOrders.js | server/src/services/integrations/travel/* | server/prisma/schema.prisma,"[""I1""]",默认 TRAVEL_SYNC_ENABLED=false +I4,通知渠道扩展(企微/钉钉),扩展通知 adapter 支持企微/钉钉模板发送并可开关,submit/approve/pay 可多渠道发送且失败不阻塞主流程,manual: mock channel 下触发三类事件验证发送与降级,manual,DONE,DONE,DONE,server/src/services/notifications/* | server/src/config.js | server/src/routes/notifications.js,"[""I1""]",默认 IM_NOTIFIER_ENABLED=false +S1,企业卡/虚拟卡管控预研,输出企业卡能力边界数据模型草案预算联动方案与ROI评估,形成 ADR 与 PoC 结论并给出做/不做建议,manual: 评审 ADR 文档与 PoC 记录,manual,DONE,DONE,DONE,docs/adr/adr-enterprise-card-control.md,"[""I1""]",none +S2,移动端路线决策预研,完成 PWA vs RN vs 小程序在离线拍照与上传可靠性方面的 PoC 对比,输出推荐路线成本风险与回滚路径 ADR,manual: 评审 ADR 文档与 PoC 对比表,manual,DONE,DONE,DONE,docs/adr/adr-mobile-strategy.md,"[""R3""]",none diff --git a/issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv b/issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv new file mode 100644 index 00000000..a9e63a36 --- /dev/null +++ b/issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv @@ -0,0 +1,9 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P9A1,invoicePool拆分方案设计与边界冻结,为超大路由文件建立拆分方案:按上传/查询/验真/运维动作分组并定义共享select与mapper边界,输出拆分清单和迁移顺序,形成可执行拆分清单且不改变现有API契约与权限模型,manual: 架构评审拆分方案并逐项确认API/权限/返回结构不变,manual,DONE,DONE,DONE,server/src/routes/invoicePool.js | server/src/routes/invoicePool/*.js | server/src/routes/invoicePool/shared/*.js,[],回滚策略=保留原入口文件并逐步转发 +P9A2,invoicePool验真路由独立化实施,将验真相关端点与事务逻辑从invoicePool主文件拆分至独立模块并保持注册路径不变,POST/GET/RETRY三个验真端点行为与错误码保持一致且主文件显著瘦身,cd server && node --check src/routes/invoicePool.js && node --check src/routes/invoicePool/verification.js && ./scripts/regression-verification.sh,manual,DONE,DONE,DONE,server/src/routes/invoicePool.js | server/src/routes/invoicePool/verification.js | server/src/routes/invoicePool/shared/selects.js,"[""P9A1""]",不改API路径=/api/invoice-pool/:id/verification* +P9A3,invoicePool共享select与响应映射收敛,提炼重复select片段与normalize逻辑到shared模块避免遗漏verification_records并降低维护成本,所有走normalizeInvoiceResponse的查询都包含必要字段且无行为回归,cd server && node --check src/routes/invoicePool.js && ./scripts/regression-workflow-actions.sh && ./scripts/regression-verification.sh,manual,DONE,DONE,DONE,server/src/routes/invoicePool.js | server/src/routes/invoicePool/shared/selects.js | server/src/routes/invoicePool/shared/mappers.js,"[""P9A2""]",不做功能增强仅做结构收敛 +P9B1,Dashboard趋势改为SQL聚合,将趋势统计由内存聚合改为数据库聚合(date_trunc/group by)并保留现有过滤与权限约束,趋势接口在大数据量下性能提升且返回结构保持兼容,manual: 对比改造前后同时间窗结果一致并在样本数据下验证响应时间,manual,DONE,DONE,DONE,server/src/routes/dashboard.js | server/prisma/schema.prisma | server/prisma/migrations/*,[],若采用queryRaw需参数化防SQL注入 +P9B2,Dashboard聚合性能回归脚本补强,为趋势与分类聚合新增性能/正确性检查步骤并接入可选回归开关,在mock数据下可重复验证聚合一致性且失败输出可定位,manual: ./scripts/regression-dashboard.sh 增加一致性断言与可选性能指标输出,manual,DONE,DONE,DONE,server/scripts/regression-dashboard.sh | server/scripts/regression-all.sh,"[""P9B1""]",保持RUN_DASHBOARD_REGRESSION默认0 +P9C1,feature-matrix纳入P6-P8能力,在矩阵中追加R1-S2对应条目并明确事实源为p6-p8 master CSV与回归覆盖映射,矩阵可一眼看到P5+P6-P8全量能力并与CSV状态一致,manual: 逐条核对issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv 与 docs/feature-matrix.md,manual,DONE,DONE,DONE,docs/feature-matrix.md | issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv,[],快照日期与范围说明需更新 +P9C2,矩阵一致性校验脚本扩展,扩展validate-feature-matrix脚本支持P5+P6-P8双事实源校验并在check-minimal维持门禁,CI可阻断矩阵与执行合同漂移且错误信息可定位到ID级别,cd /home/shunli/Projects/hyb-oa && ./scripts/check-minimal.sh,manual,DONE,DONE,DONE,scripts/validate-feature-matrix.py | scripts/check-minimal.sh | .github/workflows/ci-minimal.yml,"[""P9C1""]",保持历史CSV只读不改快照 +P9D1,P9整体验收与回归基线,汇总执行P9后最小门禁和关键回归并更新README中的前置条件说明,最小门禁通过且文档明确回归所需环境开关,cd /home/shunli/Projects/hyb-oa && ./scripts/check-minimal.sh;按需执行RUN_DASHBOARD_REGRESSION=1与RUN_VERIFICATION_REGRESSION=1,manual,DONE,DONE,DONE,server/README.md | scripts/check-minimal.sh | server/scripts/regression-all.sh,"[""P9A3"",""P9B2"",""P9C2""]",不在本Issue内新增业务功能