实现 B-2a 报销审批内容工作台(reimbursement-approval-content-workbench)

这个提交包含在:
2026-09-01 20:32:34 +08:00
父节点 4c8ee07abb
当前提交 c840574d36
共修改 36 个文件,包含 2271 行新增和 91 行删除
@@ -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,21 @@
# Design:B-2b 报销填写态共享组件迁移
## Current Decision Boundary
B-2b 不重新定义业务内容组件,而是采用 B-2a 已验证的展示模型、字段顺序和快照/实时标签;本阶段增加 edit capability、票据抽屉和提交前检查,并删除旧重复布局。
详细交互在 B-2a 真人反馈后收敛,但以下架构边界已经冻结:
- 共享组件不直接拥有 API 查询或 mutation;填写页通过显式能力和回调注入新增、编辑、删除、票据关联与恢复动作。
- review/readonly 模式不接收 edit capability,不能靠 CSS 隐藏维护动作。
- PC/移动复用同一 projection 与语义 DOM;响应式容器决定抽屉/底部 sheet 形态。
- 服务端 B2 门禁仍是提交权威,前端检查只做同合同的提前反馈。
- 旧布局在迁移验证通过后删除,不保留永久 feature flag 双实现。
## Deferred Until Entry Conditions Are Met
- 票据抽屉在 PC 使用侧栏还是对话框、移动使用 bottom sheet 还是全屏层。
- 编辑入口的最终密度、明细卡片折叠规则和提交摘要的视觉权重。
- B-2a 真人反馈要求的字段顺序微调。
这些是 B-2b 启动前要补齐的设计细节,不改变本 PRD 的迁移承诺和验收结果。
@@ -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,22 @@
# Implementation Plan:B-2b 报销填写态共享组件迁移
## Entry Gate
- [ ] B-2a 已部署并取得至少一次真人审批反馈。
- [ ] 回填本任务最终 drawer/sheet 交互与字段顺序。
- [ ] 用户重新批准更新后的 B-2b planning summary。
## Planned Sequence
1. [ ] 为 B-2a 共享组件接入 edit capability,保持 review/readonly 零维护动作。
2. [ ] PC 填写态迁移明细、票据和就近检查。
3. [ ] 移动填写态迁移相同语义结构与安全区操作。
4. [ ] 接入票据抽屉和未归属票据恢复。
5. [ ] 接入提交前摘要与服务端错误就近定位。
6. [ ] 删除被替代的旧明细/材料/只读展示分支。
7. [ ] 完成状态/权限矩阵、全量前端门禁和独立部署验证。
## Rollback
- 独立于 B-2a 形成候选与回滚点。
- 不改变 B2 服务端门禁或既有票据关联数据;代码回滚恢复旧填写 UI,不删除业务数据。
@@ -0,0 +1,71 @@
# B-2b 报销填写态共享组件迁移
## Goal
在 B-2a 共享内容组件经真实审批使用验证后,把 PC/移动报销填写态迁入同一业务结构,消除旧填写态、新审批态和旧只读态长期并存,并完成此前延期的票据抽屉与提交前检查体验。
## Entry Conditions
- B-2a 已部署并通过 PC/移动公网核验。
- 至少取得一次真实报销审批反馈,确认审批人能理解明细—票据对应、快照/实时标签和退回引用。
- B-2a 共享组件 API 已冻结;若真实反馈要求改字段顺序,先回写 B-2a 组件合同再启动迁移。
## Scope
- PC `ReimbursementDetailPage` 与移动 `MobileReimbursementDetailPage` 的 draft/rejected 填写态及非参与人只读内容投影。
- B-2a 共享组件的 edit 能力、票据抽屉、提交前检查和错误恢复。
- 删除被共享组件替代的旧明细/材料展示分支,并保持现有 API、权限和 B2 服务端门禁权威。
## Requirements
### R1 填写态采用同一业务内容组件
- PC/移动填写态、审批态和非参与人只读态共享同一“明细 + 所属票据”组件及字段顺序。
- 填写态的新增、编辑、删除、关联和恢复动作通过显式能力与回调注入;审批/只读模式不渲染这些能力。
- 删除被共享组件替代的旧明细表格、旧材料对应展示或重复只读布局,不保留永久双实现兜底。
### R2 票据抽屉围绕当前明细工作
- 员工可从明细就近添加/选择 PDF 发票,查看已关联票据和解除自己可维护状态下的关联。
- 整单补充附件仍独立,不伪装成明细票据。
- 未归属票据有明确恢复入口;不得要求员工依赖操作顺序或跳到另一大区寻找。
### R3 提交前检查进入填写路径
- 在填写过程中持续显示明细完整性、票据关联、票面金额证据和需人工核对摘要。
- 提交动作前展示与服务端 B2 一致的检查结果;服务端仍为权威,前端不得自行放宽。
- 错误就近落到明细/票据,汇总区只告诉员工还有几项及如何到达,不只在页面顶部报错。
### R4 填写与审批语义一致
- 发生日期不默认等于发票日期;跨天/跨期同一业务可作为一条明细并写明起止日期。
- 系统不自动判断明细是否应拆分,页面把它表达为填报要求和财务复核项。
- 需票明细、无票补助、manual review 和金额不可用继续遵守现有业务事实源及 B2 合同。
## Acceptance Criteria
- [ ] PC/移动填写态使用 B-2a 同一业务内容组件,审批/只读/编辑模式只在能力和动作上不同。
- [ ] 员工可在明细上下文内完成票据添加、归属查看和错误恢复,不再依赖“先明细、后整单材料区”的隐含顺序。
- [ ] 提交前检查与服务端 B2 结果一致,错误就近显示且再次提交链路可完成。
- [ ] 旧重复布局和不再使用的展示分支被删除;父任务不存在三套并行内容结构。
- [ ] PC/移动、参与人/非参与人、draft/rejected/reviewing 状态矩阵通过,既有票据/附件权限无回归。
- [ ] 公网部署和真实员工重提反馈通过后,父任务才可归档。
## Out of Scope
- 自动从票据推断发生日期或业务拆分正确性。
- 结构化退回原因和统计模型。
- 财务代员工编辑、批量改票或新审批状态。
- 与 B-2a 同批部署;本任务必须是独立候选、独立回滚点。
## Test Plan
- 组件/纯函数:review/readonly/edit 三模式字段顺序一致,能力注入不向只读视角泄漏维护动作。
- Playwright:PC/移动 participant 与 nonparticipant 的 draft/rejected/reviewing 矩阵,覆盖票据抽屉、未归属恢复、提交阻断和再次提交。
- 后端:复跑 B2 票据门禁、报销参与人授权、票据 bind/unbind/link 与材料预览聚焦套件;本任务原则上不改后端合同。
- 前端:typecheck/build、UI strict/self-test、代表性视口、键盘/读屏焦点和固定操作区遮挡检查。
- 治理:task validate、process contract、Trellis governance、敏感内容检查、`git diff --check`;部署和公网验证另行批准。
## Planning Note
本子任务当前只冻结迁移承诺和验收边界。详细 `design.md` / `implement.md` 在 B-2a 真人反馈回填后编写,避免在共享组件尚未验证前固化票据抽屉交互。
@@ -0,0 +1,26 @@
{
"id": "reimbursement-form-shared-component-migration",
"name": "reimbursement-form-shared-component-migration",
"title": "B-2b 报销填写态共享组件迁移",
"description": "在 B-2a 真人反馈后,把 PC/移动填写态迁入同一明细票据组件并删除重复旧布局。",
"status": "planning",
"dev_type": null,
"scope": "client,spec",
"package": null,
"priority": "P2",
"creator": "shunli",
"assignee": "shunli",
"createdAt": "2026-09-01",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "09-01-reimbursement-one-page-approval-workbench",
"relatedFiles": [],
"notes": "父任务第二阶段;B-2a 部署和真人反馈是启动条件,当前只冻结迁移承诺与验收边界。",
"meta": {}
}