77 行
4.2 KiB
Markdown
77 行
4.2 KiB
Markdown
# Design:B-2a 报销审批内容工作台
|
||
|
||
## 1. Change Boundary
|
||
|
||
- 扩展 workflow context 的显式预算快照投影,但不改 Prisma schema。
|
||
- 审批页继续读取 workflow task;报销内容使用现有 reimbursement detail 只读 API。
|
||
- 新建共享展示模型、分组纯函数和响应式明细证据组件。
|
||
- PC/移动审批容器接入同一组件;审批 action API、状态机和 comment 存储不变。
|
||
|
||
## 2. Data Flow
|
||
|
||
```text
|
||
GET workflow task
|
||
-> task/actions/history
|
||
-> submissionSnapshot { standardViolations, budgetCheck }
|
||
|
||
GET reimbursement detail
|
||
-> current header/items/invoices/attachments
|
||
-> current invoice amount evidence/manual review
|
||
|
||
pure projection
|
||
-> itemEvidenceModels
|
||
-> unlinkedInvoices
|
||
-> submissionCheckSummary
|
||
-> currentEvidenceSummary
|
||
|
||
PC/Mobile approval shell
|
||
-> shared evidence component
|
||
-> existing material open handlers
|
||
-> existing approve/return/reject/transfer mutations
|
||
```
|
||
|
||
两个查询任一缺少关键数据时不允许“通过”。材料单项预览失败不清空已经加载的其他证据。
|
||
|
||
## 3. Proposed Modules
|
||
|
||
- `client/src/components/reimbursements/ReimbursementItemEvidenceList.tsx`:共享响应式内容组件。
|
||
- `client/src/lib/reimbursementApprovalProjection.ts`:最小输入的分组、快照映射、实时摘要和退回引用纯函数。
|
||
- `client/src/pages/WorkflowTaskDetailPage.tsx`:PC 审批壳与右侧决策区。
|
||
- `client/src/pages/MobileApprovalsPage.tsx`:移动审批壳与底部动作层级。
|
||
- `client/src/api/workflow.ts`:显式 `budgetCheck` 类型。
|
||
- `server/src/routes/reimbursements.js`:提交时把已计算预算结果写入 context。
|
||
- `server/src/routes/workflow.js`:只投影允许的预算快照字段。
|
||
|
||
具体文件可在实施前按现有复用点微调,但不得把共享组件放进 workflow 页面目录。
|
||
|
||
## 4. Permission Matrix
|
||
|
||
| 身份/状态 | 审批页内容 | 材料原件 | 报销维护 | 审批动作 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 当前审批人 pending | 可读 | 按现有授权/审计 | 无 | 按 allowedActions |
|
||
| 已处理任务查看者 | 可读当前版本 + 历史提示 | 按现有授权/审计 | 无 | 无 |
|
||
| `expense.view_all` 财务 | 可读 | 按现有授权/审计 | 无 | 仅任务允许时 |
|
||
| 无任务/无查看资格 | 403 | 403 | 无 | 无 |
|
||
|
||
## 5. Offline Boundary
|
||
|
||
报销审批的完整证据不进入现有 workflow IndexedDB cache。`cacheWorkflowTaskDetail` 必须先把 task detail 投影为显式允许字段子集,只保留任务身份、业务公开摘要、节点/状态和必要历史;明确删除或拒绝明细、票据、附件、金额证据、材料访问数据及共享 component projection。不能把整个 DTO 透传给 IndexedDB。
|
||
|
||
离线时可查看已经允许缓存的摘要/历史,但报销审批的通过、退回、驳回和保存草稿全部不可用,并说明“需联网核对完整报销内容”。其他实体继续沿用当前离线草稿能力。
|
||
|
||
若未来需要离线报销审批,必须重新规划敏感数据缓存字段、过期、清除、加密/设备边界和附件不可离线预览,不得在 B-2a 实施中临时扩大缓存。
|
||
|
||
## 6. Test Contracts
|
||
|
||
- projection 纯函数覆盖:零/一/多票、未归属、snapshot itemId 找不到、manual review、amount unavailable、历史预算缺失、退回引用去 UUID。
|
||
- 后端覆盖:budgetCheck 与 workflow instance 同事务写入;null/旧 context 安全投影;不返回任意 context 字段。
|
||
- PC/移动 E2E 使用同一 fixture 工厂,fixture 字段由 API type/服务端 route contract 共同约束,避免两端测试作者各造一套形状。
|
||
- 完整流程断言必须点击真实可见的证据入口和审批动作;不能只断言 DOM 中存在文本。
|
||
- 离线测试在在线打开合成报销审批后读取 IndexedDB 原始记录,断言禁存字段不存在;再断网验证报销动作/草稿全部阻断,同时保留非报销审批离线基线。
|
||
|
||
## 7. Rollback
|
||
|
||
- 代码回滚恢复旧审批摘要和外链;workflow context 多出的 JSON 字段对旧代码无害。
|
||
- 不含 migration、seed、flag 或生产数据改写。
|
||
- 部署前/后按项目现有 build SHA、UI strict、公网 bundle 和合成审批任务流程核验。
|