收紧生产烟测身份治理(08-30-reimbursement-expense-policy-invoice-guard-deploy)
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-08-30 00:55:08 +08:00
父节点 faf1a0cff9
当前提交 0f9f40389e
共修改 4 个文件,包含 16 行新增和 11 行删除
@@ -30,9 +30,11 @@ B2 全局启用:同一应用候选
- admin smoke:只用于系统设置、非参与人视图和 flag 操作,不代行财务审批。
- employee smoke:从当前 5 人部门迁入已确认零成员的隔离部门,建立合成草稿并验证 owner 合同;终态常驻该部门,不再迁回。
- manager smoke:新建 manager + employee 的 OA-only 专用身份并设为 employee smoke 的直属 manager。普通 employee 没有直属 manager 时,提交会被 `no_manager_found` 阻断,不会走 finance fallback。
- finance smoke:新建 finance + employee 的 OA-only 专用身份,放入隔离部门,用于财务只读投影;不恢复已消失旧账号,不绑定真人身份。
- finance smoke:新建 finance + employee 的 OA-only 专用身份,放入隔离部门,用于财务只读投影;不恢复已消失旧账号,不绑定真人身份。因为完整 finance 角色包含付款能力,账号在验收窗口外保持 disabled,每次启停均需生产账号写入授权。
- 真实 finance:仅负责 4 张真人单据的业务退回和重提复核,凭据不交给自动化。
隔离部门改名为“系统测试专用(勿分配员工)”。名称用于降低 HR 误分配概率,但每次灰度仍必须以实时成员集合为准:只允许 employee/manager/finance 三个 smoke,任何第四个成员都使灰度门关闭。
合成材料必须是无真实抬头、号码、账户和业务正文的测试 PDF/图片。成功提交的合成单据通过 owner 撤回回到草稿再删除;阻断场景直接删除草稿。审计记录保留。
## Migration 与 seed
@@ -51,9 +53,9 @@ B2 全局启用:同一应用候选
1. B1 init 后确认 DB flag 记录已由 seed 显式创建为 `force_off`,不得接受 `missing_flag_record`,并保存完整快照。
2. 经生产配置授权把 env hard gate 设为 true,重启同一候选。
3. 验证 `envEnabled=true`、`effectiveEnabled=false`、reason=`flag_force_off`。
4. 经灰度授权把 DB 更新为 department allowlist,仅含隔离部门。
4. 经灰度授权前实时确认隔离部门只有三个 smoke,并在获批窗口临时启用 finance smoke;随后把 DB 更新为 department allowlist,仅含隔离部门。
5. 执行合成验证;失败恢复调用前快照,优先 `force_off`。
6. 灰度 PASS 后,经全局授权更新为 global force_on。
6. 灰度 PASS 后,经全局授权更新为 global force_on;验收窗口结束立即 disabled finance smoke。
flag 更新使用 API 的 expectedVersion 并发控制并自动写审计。关闭 flag 只改变后续行为,不删除已建立的关联。
@@ -8,9 +8,10 @@
## 2. 验收准备(独立生产写入授权)
- [ ] 再次只读确认隔离部门零真人成员,把它固定为常驻 smoke 部门。
- [ ] 再次只读确认隔离部门零真人成员,经生产写入批准改名为“系统测试专用(勿分配员工)”,并固定为常驻 smoke 部门。
- [ ] 新建 OA-only manager smoke(manager + employee)与 finance smoke(finance + employee),凭据写入私有 smoke env,不输出、不绑定真人。
- [ ] 把 employee smoke 迁入常驻 smoke 部门,将 manager smoke 设置为其直属 manager;先用合成空壳草稿确认 workflow 可分配,再创建明显标识的合成历史草稿和非真实票据/附件。
- [ ] finance smoke 创建后默认 disabled;验收窗口开始前经单独批准临时启用,窗口结束立即 disabled。不得让持付款能力的 smoke finance 常驻 active。
- [ ] 明确授权材料合并预览产生设计内审计记录;真实材料不落测试报告。
## 3. Push 与来源门禁
@@ -44,7 +45,7 @@
## 7. B2 隔离灰度(独立 flag 授权)
- [ ] 用 expectedVersion 把 flag 更新为 `force_on + department_allowlist + 隔离部门`;受控容器内只读诊断确认隔离部门 reason=`flag_force_on_department_allowed`、名单外 reason=`department_not_allowed`,并与详情 DTO `invoiceGuardEnabled` 交叉核对。
- [ ] 灰度前实时读取隔离部门成员,确认恰好只有 employee/manager/finance 三个 smoke、无真人;临时启用 finance smoke 后,用 expectedVersion 把 flag 更新为 `force_on + department_allowlist + 隔离部门`。受控容器内只读诊断确认隔离部门 reason=`flag_force_on_department_allowed`、名单外 reason=`department_not_allowed`,并与详情 DTO `invoiceGuardEnabled` 交叉核对。
- [ ] 合成验证 owner 普通提交成功。
- [ ] 合成验证两项无票补助不被阻断。
- [ ] 合成验证多票显式关联成功。
@@ -59,7 +60,7 @@
- [ ] 灰度七项全 PASS,成功合成单据已撤回并删除,失败草稿已删除;审计历史保留。
- [ ] 用户单独批准 global enable;用 expectedVersion 更新为 global force_on。
- [ ] 验证全局 effective on、reason=`flag_force_on_global`、owner 基线、非参与人只读、错误提示、runtime 指标和审计记录。
- [ ] employee/manager/finance smoke 常驻隔离部门,确认部门仍无真人成员;不再执行迁回写入。
- [ ] employee/manager/finance smoke 常驻隔离部门,确认成员集合仍只有三个 smoke且无真人;不再执行迁回写入,finance smoke 在窗口结束后立即 disabled。
## 9. 四张真实单据退回与重提
@@ -36,7 +36,8 @@
### R2 验收身份与合成数据
- 不恢复已从用户表消失的旧 manager/finance smoke;新建角色纯净的 OA-only manager smoke(manager + employee)和 finance smoke(finance + employee),不绑定或重置真实员工身份。
- 把已确认无成员的部门固定为常驻 smoke 部门;employee smoke 迁入后不再迁回,manager smoke 设置为其直属 manager,三类 smoke 身份留在该部门供后续隔离灰度复用。迁移前再次确认部门仍无真人成员。
- 把已确认无成员的部门改名为“系统测试专用(勿分配员工)”并固定为常驻 smoke 部门;employee smoke 迁入后不再迁回,manager smoke 设置为其直属 manager,三类 smoke 身份留在该部门供后续隔离灰度复用。迁移前以及每次部门灰度开启前,都必须确认成员集合恰好只有这三个 smoke;部门名称只是防误用提示,不能替代成员集合校验。
- finance smoke 持有完整 finance + employee 角色,包含付款和全量财务职责,因此只允许在单独获批的验收窗口内启用。窗口结束后立即置为 disabled;后续再次启用、使用和停用都属于生产账号写入,不得从既往验收授权推定。
- 普通 employee 缺直属 manager 时,报销提交会因 `blockOnUnresolvedAssignee=true` 和 `no_manager_found` 返回 409;`owner_self_fallback_role=finance` 只处理 owner 本人持有 CEO 角色的特殊情形,不得把 finance fallback 当作普通 smoke 的兜底方案。
- 合成草稿、明细、票据和附件必须使用明显测试标识与非真实材料;不得复制真人票据、金额、说明或附件。
- 所有成功提交的合成单据在验证后按合法 owner 流程撤回并删除;失败场景草稿直接删除。审计/工作流历史按系统合同保留,不做数据库硬删。
@@ -54,6 +55,7 @@
- B1 验收通过后,先确认 DB 为 `force_off`,再经单独生产配置批准把 `REIMBURSEMENT_INVOICE_GUARD_ENABLED=true` 写入受控生产 env,并重启同一候选。重启后应显示 env enabled 但 effective off。
- 隔离灰度只能将 DB flag 设置为 `force_on + department_allowlist + 隔离部门 ID`;不得使用 employee smoke 原部门,不得把 4 张真人单据作为灰度样本。
- 更新部门 allowlist 前必须重新读取部门成员与状态,确认只有 employee/manager/finance 三个 smoke、无真人成员,且 finance smoke 仅在当前获批窗口临时启用;任何额外成员或身份不确定都阻断灰度。
- 每个状态必须记录精确 reason:env 未开为 `env_hard_off`;env on + DB off 为 `flag_force_off`;灰度名单外部门为 `department_not_allowed`;隔离部门在本轮 `force_on` 模式下为 `flag_force_on_department_allowed`;全局开启为 `flag_force_on_global`。不得只凭提交成功/失败推断门禁已运行。
- 普通 feature flag 列表使用 `strictDepartment=false`,在部门 allowlist 状态只能给出延后判断,不能证明具体 actor 命中。灰度证据必须运行受控容器内只读 actor/department 诊断,并与报销详情 DTO 的 `invoiceGuardEnabled` 交叉验证;诊断不输出部门 ID、账号或原始 payload。
- 隔离灰度必须验证:owner 普通提交成功;两项无票补助不被阻断;多票显式关联成功;超票面准确阻断;旧草稿补齐后可提交;非参与人零写入副作用;切回 `force_off` 后旧提交路径恢复且既有关联数据不删除、不解绑。
@@ -77,7 +79,7 @@
## Acceptance Criteria
- [ ] 常驻 smoke 部门、专用 manager/finance smoke、employee smoke 迁入和直属 manager 关系经单独生产写入批准;准备完成后不涉及任何真实员工身份或材料。
- [ ] 常驻部门已改名为“系统测试专用(勿分配员工)”;专用 manager/finance smoke、employee smoke 迁入和直属 manager 关系经单独生产写入批准,成员集合只有三个 smoke且不涉及任何真实员工身份或材料。
- [ ] 最终候选冻结、单独 push、upstream 祖先关系和严格 provenance 全部通过。
- [ ] 用户在 provenance 通过后另行批准 B1 生产部署;pre/post migration status 均明确记录,唯一 migration 正确应用。
- [ ] B1 schema、费用主数据、requires_invoice、assets 批准依据、2,000 元提示和 account code 保留检查通过;B2 DB 记录明确存在且为 force_off,effective off reason 不是 missing record。
@@ -85,7 +87,7 @@
- [ ] owner 合成草稿维护正常;finance/admin 非参与人无维护入口;材料合并预览成功并只产生获批的设计内审计。
- [ ] env hard gate 在 DB `force_off` 状态下单独启用并重启,确认 env on / effective off 后才进入隔离灰度。
- [ ] B2 隔离灰度七项合同全部通过;失败时 DB 快照恢复,既有关联数据未回滚。
- [ ] 用户单独批准后 B2 全局 effective on;合成数据已按合法流程清理,employee/manager/finance smoke 常驻隔离部门且无真人混入。
- [ ] 用户单独批准后 B2 全局 effective on;合成数据已按合法流程清理,employee/manager/finance smoke 常驻隔离部门且无真人混入,finance smoke 已在验收窗口结束后 disabled。
- [ ] 真实财务按明确说明退回 0014/0016/0017/0018,重提后人工复核日期粒度;0008 与 0013 未被误改。
- [ ] 任一失败按固定回滚/补偿边界处理,无 reset、无逆 migration、无批量伪造批准依据或票据关联。
- [ ] 所有公网门禁完成前不通知普通用户测试、不归档父任务。
@@ -28,6 +28,6 @@
"server/src/services/featureFlags/index.js",
"server/src/routes/reimbursements.js"
],
"notes": "规划阶段;不执行 push、生产账号/部门/合成数据写入、migration、部署、env 配置、feature flag 更新或真实单据退回。固定应用回滚基线为 59dc5f6。B2 不校验日期粒度,0014 必须依赖退回说明和财务人工复核。employee/manager/finance smoke 终态常驻隔离部门;普通 employee 无直属 manager 时 workflow 会以 no_manager_found 阻断。B2 DB 记录必须显式存在为 force_off,灰度必须记录 actor 级精确 reason。",
"notes": "规划阶段;不执行未单独授权的 push、生产账号/部门/合成数据写入、migration、部署、env 配置、feature flag 更新或真实单据退回。固定应用回滚基线为 59dc5f6。B2 不校验日期粒度,0014 必须依赖退回说明和财务人工复核。employee/manager/finance smoke 终态常驻‘系统测试专用(勿分配员工)’部门;每次灰度前成员集合必须恰好为三个 smoke。finance smoke 含付款能力,仅在获批验收窗口临时 active,窗口外 disabled。普通 employee 无直属 manager 时 workflow 会以 no_manager_found 阻断。B2 DB 记录必须显式存在为 force_off,灰度必须记录 actor 级精确 reason。",
"meta": {}
}