# 2026-06-09 报销审批自动回调闭环验证

更新时间：2026-06-09 19:49 CST

## 当前结论

公司财务报销系统的「系统入库 → 发起飞书审批 → 飞书自动回调 → 系统状态回写」链路已经用真实测试审批验证通过。

当前可信口径：

1. 公司财务系统 PostgreSQL 仍是报销账本 source of truth；飞书审批是审批流和审计边界。
2. 报销草稿先进入 `intake_draft`，提交后进入 `reimbursement_order` / `reimbursement_item`。
3. 飞书审批实例创建成功后，实例 ID 同步绑定到草稿和报销单。
4. 飞书审批通过后，真实自动 webhook 会回写系统状态为 `APPROVED`。
5. 飞书会在 `APPROVED` 后继续推送无业务状态的 `approval` 类事件；系统只把这类事件记入 `approval_callback_event` 审计，不允许其用 `UNKNOWN` 覆盖已经终态的 `APPROVED`、`REJECTED`、`PAID`。
6. `APPROVED` 的业务含义是审批通过/待打款；付款发生后仍需要通过后续资金流水或打款核销流转到 `PAID`。

## 已验证测试单

| 测试目的 | 系统报销单 | 草稿 ID | 飞书实例 ID | 飞书流水号 | 金额 | 最终状态 |
| --- | --- | --- | --- | --- | ---: | --- |
| 真实自动回调基础验证 | `RB20260609-97CB911E` | `drf_1780997533647_982ddc0b` | `32F25E1C-6235-402B-A425-22FBBB7ABD67` | `202606090005` | 0.01 | `APPROVED` |
| `UNKNOWN` 不覆盖 `APPROVED` 回归验证 | `RB20260609-F392C5DA` | `drf_1781000182695_bb81b389` | `C8EE2972-EAEF-4244-9F84-ED3B0F512725` | `202606090006` | 0.01 | `APPROVED` |
| 有票报销附件链路验证 | `RB20260609-CC5EAD97` | `drf_1781002073981_907a7b0b` | `4E8DA5D2-4229-4281-B338-815AB9D268EA` | `202606090007` | 0.01 | `APPROVED` |

线上 API 回查到三张测试单均为：

```text
status=APPROVED
approval_instance_id 已绑定
approved_at 已写入
total_amount=0.01
```

## 回调事件证据

服务器数据库 `approval_callback_event` 在 2026-06-09 17:30 后统计：

```text
callback_events = 18
approved_events = 9
unknown_events = 3
```

三张关键测试单的事件分布一致：

```text
每个 approval_instance_id：
- APPROVAL_PENDING: 2
- APPROVED: 3
- UNKNOWN: 1
```

这说明飞书自动推送了审批中和审批通过事件，也推送了后续无状态事件；当前系统的状态守卫已生效，最终业务状态保持 `APPROVED`。

## 附件与有票报销口径

有票测试单验证了两层附件：

1. 系统审计归档层：附件入库为 `attachment_type=invoice`，存储提供方包含 `tencent_cos`。
2. 飞书审批表单层：同一测试 PDF 上传到飞书审批附件接口，并把返回的 approval file code 传给模板 `附件` 控件。

注意：本次有票测试使用合成 PDF，只验证附件上传、审批表单绑定、审批回调和状态回写；不代表真实发票 OCR/结构化导入已完成。合成 PDF 对应的 `invoice_rows=0` 是预期结果。

## 当前仍未覆盖的边界

- 真实发票 PDF 的结构化解析、发票号码去重和税额校验。
- 审批通过后的实际打款、资金流水入账和 `PAID` 核销。
- 付款失败、审批拒绝、撤回/取消等异常分支的完整回归测试。

## 文档同步位置

本结论已同步到：

- `PROJECT_CONTEXT.md`
- `README.md`
- `docs/云端部署与报销闭环说明.md`
- `docs/feishu_reimbursement_approval_backend_flow.md`
- `docs/deployment_log.md`
