修复(08-28-reimbursement-review-routing-copy): 规范财务兜底文案
这个提交包含在:
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,47 @@
|
||||
# 设计:报销规范核查与审批文案优化
|
||||
|
||||
## 边界
|
||||
|
||||
本任务包含两个相互关联但可独立验证的输出:生产 4 笔报销的只读规范性报告,以及负责人本人财务兜底节点的用户文案修复。前者不写业务数据;后者只调整步骤命名与详情显示投影,不改审批规则、角色、权限或数据库结构。
|
||||
|
||||
## 数据流
|
||||
|
||||
### 报销核查
|
||||
|
||||
```text
|
||||
生产只读数据 → 按提交人/日期冻结 4 个业务编号 → 最小字段核查
|
||||
→ 对照报销/发票/附件事实源 → 脱敏逐笔结论
|
||||
```
|
||||
|
||||
- 优先使用现有受控生产只读连接或已授权 API 身份。
|
||||
- 查询结果只在进程内用于判断;任务文档只登记问题分类、业务编号和必要的非敏感摘要。
|
||||
- 不打开或下载原始附件时,只把“需要财务查看原件”列为保留项,不推断真实性。
|
||||
|
||||
### 审批文案
|
||||
|
||||
```text
|
||||
审批规则解析
|
||||
→ buildRoleApprovalStep(保存步骤 ID、角色与业务步骤名)
|
||||
→ workflow task / workflow_steps_snapshot(历史事实)
|
||||
→ reimbursement processingProgress 显示投影
|
||||
→ 当前处理 / 下一步 / 时间线
|
||||
```
|
||||
|
||||
负责人本人兜底的技术原因继续由步骤 ID 后缀 `_owner_self_fallback`、分支原因和角色规则表达。业务步骤名改为按角色映射后的 `财务复核`,避免新记录继续污染用户入口。针对已经保存旧步骤名的历史记录,`resolveApprovalStageLabel` 将 `负责人本人申请兜底:<role>` 识别为内部标签,再按 `assignee_role` 映射为 `财务复核`。
|
||||
|
||||
`processingProgress` 当前阶段的 `detail` 不再拼接旧步骤名,而使用规范化后的 stage label,因此详情页现有 `nextStepText` 可直接显示 `待财务复核处理`。前端无需引入第二套文案映射。
|
||||
|
||||
## 兼容性
|
||||
|
||||
- 不回写历史工作流实例或任务。
|
||||
- 普通的自定义可读节点名继续保留;只把明确的负责人本人兜底内部标签、序号、通用名和技术标识走角色映射。
|
||||
- `finance` 与 `finance_mgr` 的显示均为 `财务复核`;审批资格仍按原角色执行。
|
||||
- 报销审批历史如直接读取旧 `step_name`,需在同一服务端显示边界复用规范化函数,避免详情页不同区域一处修好、一处仍泄漏。
|
||||
- 待办中心的历史任务若仍直接暴露旧名,本任务只做必要的共享显示归一化,不改变任务 API 的权限与动作模型。
|
||||
|
||||
## 风险与回滚
|
||||
|
||||
- 风险:过宽地判定“不可读节点名”会覆盖合法自定义名称。控制方式是只增加负责人本人兜底前缀的精确识别,并保留现有名称优先级测试。
|
||||
- 风险:仅改生成名无法修复已经提交的 4 笔。控制方式是在读取投影层同时兼容历史名。
|
||||
- 回滚:代码回退即可;无 schema、配置或数据回滚。
|
||||
- 公网部署不在默认执行范围,必须另行明确批准。
|
||||
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,44 @@
|
||||
# 实施清单:报销规范核查与审批文案优化
|
||||
|
||||
## 1. 只读核查
|
||||
|
||||
- [x] 确认受控生产只读访问方式,不打印或持久化凭据。
|
||||
- [x] 按 `majianyong`、提交日期 `2026-08-28` 查询并冻结 4 个业务编号;数量漂移则停止。
|
||||
- [x] 读取最小核查字段,逐笔完成事由、项目、明细、日期金额、发票对应和补充材料检查。
|
||||
- [x] 形成脱敏结论与建议,不执行任何报销、附件、审批、付款或企微写操作。
|
||||
|
||||
## 2. 文案实现
|
||||
|
||||
- [x] 修改负责人本人兜底步骤的业务名称,保留内部步骤 ID 和审批路由原因。
|
||||
- [x] 扩展报销处理进度的显示归一化,兼容 4 笔已保存的旧快照和任务名。
|
||||
- [x] 让当前阶段 detail 使用规范化的节点标签,得到 `待财务复核处理`。
|
||||
- [x] 检查审批历史、PC 待办和移动待办的直接消费路径,只修复会继续暴露相同内部标签的位置。
|
||||
|
||||
## 3. 测试与复核
|
||||
|
||||
- [x] 补充 workflow 和 reimbursement detail 聚焦单测,覆盖新旧步骤名及普通链路。
|
||||
- [x] 运行后端语法、Prisma、聚焦 Vitest。
|
||||
- [x] 运行前端 typecheck/build 与聚焦 PC 报销详情 Playwright。
|
||||
- [x] 主会话进行只读 diff 复核,确认自审、权限、状态机、任务推进、历史快照和审批规则未改变。
|
||||
- [x] 运行流程、文档、Trellis 治理和 `git diff --check`。
|
||||
|
||||
## 4. 交付边界
|
||||
|
||||
- [x] 汇总 4 笔脱敏核查结论、代码变化和验证结果。
|
||||
- [x] 如需公网部署,先向用户单独申请批准;部署前不执行生产写入,部署后通过 `/ready`、构建号和公网只读检查后才能通知测试。
|
||||
|
||||
## 脱敏核查结论
|
||||
|
||||
- `BX-20260828-0014`:硬件类 5 张发票合并为 1 条明细,发票日期跨 5—7 月但明细只填一个日期;金额超过 2 万元且无订单、验收或资产信息附件。建议撤回后按实际设备/采购批次拆分,补用途、使用人/保管人、订单验收和资产候选说明。
|
||||
- `BX-20260828-0016`:4 张外部技术服务发票合并为 1 条笼统明细,发票日期跨 5—6 月且均未关联具体明细,无服务范围、服务期间、成果或订单/合同摘要材料。建议撤回后按服务事项或期间拆分并补业务依据。
|
||||
- `BX-20260828-0017`:2 张办公用品发票未关联明细,发票合计与申报金额相差 1,949.81 元;虽有 2 张图片附件,但材料类型和名称不能说明是支付、订单、验收或差额说明。建议撤回核对申报金额,逐票关联并明确差额和附件用途。
|
||||
- `BX-20260828-0018`:5 张办公用品发票金额合计与申报一致,但均未关联明细;明细日期晚于全部发票日期,事由和说明仅写“办公用品采购”,无订单/物品清单或用途材料。建议撤回后按购买内容/日期拆分并逐票关联。
|
||||
|
||||
本轮仅执行生产只读 SQL;未打开或下载发票原件和附件,未写生产数据库、审批、付款或企业微信。
|
||||
|
||||
## 关键文件与回滚点
|
||||
|
||||
- `server/src/utils/workflow.js`:新工作流步骤业务名;回退单个命名分支即可。
|
||||
- `server/src/routes/reimbursements.js`:历史显示投影;回退标签识别与 detail 生成即可。
|
||||
- `server/tests/unit/utils/workflow.test.js`、`server/tests/unit/routes/reimbursements.detail.test.js`:聚焦回归。
|
||||
- 如待办入口确需同步,优先复用已有显示函数或服务端投影,不新增页面级散落映射。
|
||||
@@ -0,0 +1,71 @@
|
||||
# 报销规范核查与审批文案优化
|
||||
|
||||
## Goal
|
||||
|
||||
核查 `majianyong` 于 2026-08-28 提交的 4 笔报销是否满足当前报销、发票和附件规范,并将“负责人本人申请兜底:finance”这类内部审批路由说明替换为用户能直接理解的财务处理文案,同时保持禁止自审和历史审批事实不变。
|
||||
|
||||
## Background
|
||||
|
||||
- 用户反馈 `majianyong` 当前提交了 4 笔填写不够规范的报销,并提供了其中 `BX-20260828-0018` 的详情截图。
|
||||
- 截图可确认该单为办公用品报销:整单事由与唯一明细说明均为泛化的“办公用品采购”,未关联项目;5 张发票自动归入 1 条总额明细,材料对应区提示“待关联发票或补充无票说明”。
|
||||
- 当前正式组织口径是 `majianyong` 为公司负责人 `ceo`、不配置直属主管且不得自审;负责人本人提交报销时由唯一 active 非本人 `finance` 处理。
|
||||
- 后端在生成负责人本人兜底步骤时把内部原因和角色代码拼为 `负责人本人申请兜底:finance`,报销详情的处理进度投影把它当作可读节点名,因而在“下一步”“当前处理”和时间线中直接展示。
|
||||
- 现有稳定规约已经规定审批投影不得暴露角色代码或技术标识,`finance|finance_mgr` 应显示为“财务复核”。
|
||||
|
||||
## Scope
|
||||
|
||||
- 生产 4 笔报销的最小字段只读核查与脱敏结论。
|
||||
- 负责人本人财务兜底步骤的新记录业务命名。
|
||||
- 报销详情、PC/移动审批任务等用户入口对历史兜底步骤名的只读显示投影。
|
||||
- 聚焦后端回归、前端构建与报销详情页面验证;不包含公网部署。
|
||||
|
||||
## Requirements
|
||||
|
||||
### R1 生产报销只读核查
|
||||
|
||||
- 只读定位 `majianyong` 在 2026-08-28 提交的 4 笔报销;若实际结果不恰好为 4 笔,应停止逐笔结论并报告范围漂移。
|
||||
- 仅读取核查所需的最小字段:业务编号、状态、报销日期、事由、项目关联、费用类型、明细日期/金额/说明、发票与明细关联状态、补充附件类型/说明、材料完整性提示和审批节点摘要。
|
||||
- 按当前事实源检查:事由和明细说明是否能说明购买/支出内容及业务用途;费用类型和日期是否准确;项目性费用是否关联项目;多张发票是否合理拆分或能与明细对应;发票是否逐条关联;支付截图、订单或情况说明等补充材料是否足以支撑实付与用途。
|
||||
- 输出逐笔脱敏问题清单,区分“应退回补正”“建议补充”“仅需财务核对”;不得在任务文件、仓库或聊天中记录完整发票号码、附件原文、原始 payload、账号、凭据或存储路径。
|
||||
- 本任务不替用户编辑、撤回、审批或付款,不写生产数据库,不写企业微信。
|
||||
|
||||
### R2 用户可见审批文案
|
||||
|
||||
- `owner_self_fallback` 继续作为内部路由/审计语义,仍须保持 active 非本人财务处理和禁止自审。
|
||||
- 报销详情中该节点统一显示为 `财务复核`;“当前处理”按现有结构显示 `财务复核 · <实际处理人姓名>`,不显示内部角色代码;“下一步”显示 `待财务复核处理`。
|
||||
- 处理进度时间线对当前和历史负责人本人兜底快照均显示 `财务复核`,不得要求迁移或重写历史 `workflow_steps_snapshot`。
|
||||
- 新提交报销生成的业务步骤名使用可读文案,内部兜底原因保留在稳定步骤 ID/路由逻辑中,不能因文案调整丢失自审保护或审批人解析依据。
|
||||
- 聚焦核对待办/移动审批等直接使用任务步骤名的用户入口;如它们会继续暴露该内部文案,应复用同一服务端显示语义或确保新任务不再生成内部文案。不得进行通用工作流 UI 重构。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] 生产只读结果恰好覆盖 `majianyong` 于 2026-08-28 提交的 4 笔报销,并形成不含敏感原文的逐笔规范性结论。
|
||||
- [x] 每笔结论至少覆盖事由、项目、明细拆分/说明、日期与金额、发票对应、补充材料六类检查,并给出明确处理建议。
|
||||
- [x] `BX-20260828-0018` 不再把 5 张发票仅以泛化“办公用品采购”视为充分说明;结论明确指出其明细对应和用途证据缺口。
|
||||
- [x] 负责人本人申请仍只由 active 非本人 `finance` 处理,不产生自审、不改变普通员工审批链。
|
||||
- [x] 报销详情的“当前处理”“下一步”和处理进度不再显示 `负责人本人申请兜底`、`finance` 或其他内部步骤标识,分别使用“财务复核 · 处理人”“待财务复核处理”和“财务复核”。
|
||||
- [x] 已存在的历史兜底快照无需数据迁移即可得到同样的用户可读投影;新提交记录不再生成内部原因作为用户可见步骤名。
|
||||
- [x] 后端聚焦测试覆盖历史步骤名、新步骤名、普通财务节点、非财务节点与禁止自审回归;相关前端类型检查、构建和报销详情 Playwright 通过。
|
||||
- [x] 审批/workflow 变更完成后进行一次只读代码复核,确认权限、状态机、快照和审批规则语义未扩大。
|
||||
- [x] 未经另行批准不部署公网;部署并通过公网只读检查前,不告知用户线上可测试。
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 修改、撤回、驳回、通过这 4 笔真实报销,或替员工补录材料。
|
||||
- 修改审批角色、负责人直属主管、审批金额档、生产审批规则或历史快照。
|
||||
- 执行真实付款、付款批次操作、附件下载、企业微信写入或数据库迁移。
|
||||
- 新增通用 BPM、重构全部业务域审批文案或改变现有页面布局。
|
||||
|
||||
## Risks and Constraints
|
||||
|
||||
- 生产数据可能已发生状态变化;只读查询必须冻结查询时间并以业务编号为结论锚点。
|
||||
- 发票 PDF 和支付证明需要人工看原件才能判断真实性;本轮自动/字段核查只能判断材料结构与对应关系,不能替代财务验真。
|
||||
- 历史快照是审批事实,文案修复必须在显示投影层兼容,不得回写历史数据。
|
||||
|
||||
## Test Plan
|
||||
|
||||
- 聚焦后端:`cd server && npx vitest run tests/unit/utils/workflow.test.js tests/unit/routes/reimbursements.detail.test.js`。
|
||||
- 基础后端:`cd server && npm run prisma:validate`,修改的 JavaScript 文件执行 `node --check`。
|
||||
- 前端:`cd client && npm run typecheck && npm run build`;运行覆盖 PC 报销详情的聚焦 Playwright。
|
||||
- 流程治理:`node scripts/qa/check-process-contract.mjs --baseline --json`、`node scripts/qa/audit-docs.mjs --check-registry`、`node scripts/qa/check-trellis-governance.mjs`、`git diff --check`。
|
||||
- 人工只读复核:检查 diff 未改变审批资格、任务推进、历史快照持久化或生产数据。
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "reimbursement-review-routing-copy",
|
||||
"name": "reimbursement-review-routing-copy",
|
||||
"title": "报销规范核查与审批文案优化",
|
||||
"description": "只读核查 majianyong 的 4 笔报销规范性,并修正负责人本人财务兜底节点的用户可见文案。",
|
||||
"status": "in_progress",
|
||||
"dev_type": null,
|
||||
"scope": "server/workflow and reimbursement display projection; production reimbursement read-only review",
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-28",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户