# 附件上传风险前置复核 TODO

## 调研与契约

- [x] 盘点附件上传、预审、提交链路，确认完整风险复核当前在提交阶段重复执行。[CONCEPT: 背景与问题]
- [x] 明确上传后复核 helper 的输入输出契约，不新增业务字段。[CONCEPT: 方案设计] 证据：新增 `_refresh_claim_pre_review_flags()` 复用现有风险字段。

## 后端实现

- [x] 在附件上传完成后触发报销级风险复核，并保持单据状态为草稿。[CONCEPT: 功能能力] 证据：`upload_claim_item_attachment()` 调用 `_refresh_claim_pre_review_flags()`。
- [x] 上传后风险复核写回 `ai_pre_review` 和 `submission_review` 风险结果。[CONCEPT: 功能能力] 证据：`test_upload_attachment_refreshes_claim_pre_review` 通过。
- [x] 规则中心风险在上传后写入 `risk_observations`，避免提交阶段集中写入。[CONCEPT: 方案设计] 证据：上传后复核复用 `_run_ai_submission_review()`，平台风险仍调用 `RiskObservationService.upsert_platform_risk_flags()`。
- [x] 提交阶段改为读取既有风险结果，只做最终校验、预算占用和流转。[CONCEPT: 目标与非目标] 证据：`submit_claim()` 仅在缺少 `ai_pre_review` 时兜底复核。
- [x] 保留“无附件直接提交”的兜底检查，避免绕过风险复核。[CONCEPT: 风险与开放问题] 证据：`test_submit_claim_runs_ai_review_and_routes_to_direct_manager` 通过。

## 前端实现

- [x] 确认上传完成后 UI 使用接口返回的 `claim_risk_flags` 刷新 AI 建议与行风险标识。[CONCEPT: 前端] 证据：`travel-request-detail-risk-advice.test.mjs` 通过。
- [x] 确认提交阶段不恢复阻塞弹窗，只显示轻量后台提交提示。[CONCEPT: 前端] 证据：`travel-request-detail-submit-confirm.test.mjs` 通过。

## 测试与验证

- [x] 后端测试：附件上传后自动生成预审风险结果。[CONCEPT: 测试方案] 证据：`test_upload_attachment_refreshes_claim_pre_review` 通过。
- [x] 后端测试：提交阶段不重复调用完整风险复核。[CONCEPT: 测试方案] 证据：`test_submit_claim_reuses_upload_pre_review_without_rerunning_review` 通过。
- [x] 后端测试：风险观测仍被持久化。[CONCEPT: 测试方案] 证据：`test_risk_observation_storage_ready_is_cached_per_bind` 通过。
- [x] 前端回归测试通过。[CONCEPT: 测试方案] 证据：54 个详情页风险/提交测试通过。
- [x] `npm.cmd --prefix web run build` 通过。[CONCEPT: 测试方案] 证据：前端生产构建通过，仅保留既有 Rollup 注释与 chunk size 警告。
- [x] Docker `x-financial-main` 容器内后端定向测试通过。[CONCEPT: 测试方案] 证据：核心上传前置复核、提交复用预审、申请/报销风险回归测试通过。
