5.7 KiB
5.7 KiB
杨俊报销就绪:技术设计
1. 设计目标
以最小生产变更打通“杨俊企微登录 → 杨俊提交真实报销 → 马建勇审批 → 王芝玲财务处理”。本任务不新增产品能力,复用现有通讯录导入、用户主管写入、报销工作流和异机备份能力。
2. 已确认边界
- 企业微信成员与 OA 员工是两个独立事实:杨俊已在企微通讯录,但生产尚无 OA 员工记录和企微绑定。
- 单人通讯录输入可唯一筛出杨俊;手机号为空符合现有 nullable 合同,企业邮箱存在,
incomplete=0。 - 生产已有 37 个 active 费用类型和 1 个 active 报销工作流定义。
- active 法体为 0,但当前报销创建、提交和费用控制不以法体为硬门禁,本任务不创建法体。
- 杨俊的真实直属主管由用户确认是马建勇。
- 自动备份 daily/watchdog/drill-reminder 与 WARCH3 service 的
BUILD_SHA均已漂移,必须先修复。
3. 数据流与执行门禁
现场只读复核活动构建与 4 个 unit
→ 重装 automatic-backup 三项 timer/service 与 WARCH3 timer
→ 验证 unit BUILD_SHA、enabled、active
→ 手工触发一份真实自动异机备份
→ 验证源端成功与 ARM 恢复点完整/新鲜
→ 从管理员导出通讯录在内存中仅筛选杨俊
→ production dry-run(create=1、conflict/skip/fail=0)
→ production apply(初始角色仅 employee)
→ 验证 OA 员工 active、企微绑定唯一、其他成员未导入
→ 通过现有用户管理接口设置 direct_manager_id=马建勇
→ 验证主管 active、不同人、具备 expense.approve,并核对审计
→ 杨俊本人企微登录并提交真实报销
→ 马建勇审批,随后进入王芝玲财务处理链路
任一门禁失败即停止后续步骤,不用后续成功掩盖前序失败。
4. 复用合同
4.1 通讯录导入
- 复用
server/src/scripts/import-wecom-directory-export.js的 stdin 输入,不把筛选后的 XLSX 或成员原始 payload 写入磁盘、日志、Trellis 或聊天。 - dry-run 只记录人数与结果计数。
- apply 必须同时满足脚本
--apply参数和容器内WECOM_DIRECTORY_EXPORT_APPLY=1。当前 Compose v1 调用必须显式使用docker-compose exec -T -e WECOM_DIRECTORY_EXPORT_APPLY ...,不能只在宿主 shell export。 - 输入严格只有杨俊一人;成功创建后的初始角色集合严格为
employee,不导入其他通讯录成员。 - 此路径是“管理员导出企微通讯录 → OA 员工/身份绑定”的单向导入。OA 侧主管字段仅服务 OA 工作流;不调用企微成员 create/update/disable,也不把 OA 主管、姓名、部门、手机或邮箱写回企微。
- 企微成员资料如需变化,由成员本人在企微允许的入口修改,或由企微管理员在管理后台修改;OA 后续只通过重新导出/受控同步读取变化。
4.2 直属主管
- 复用
POST /api/users/batch/set-manager,不直写数据库。 - 写入目标仅杨俊,主管仅马建勇;接口负责 active、自指等现有校验。
- 写后核对
SYSTEM_USERS_BATCH_SET_MANAGER审计增量,不记录完整账号或原始请求体。 - 马建勇必须是 active、与杨俊不同且按有效角色解析出
expense.approve。
4.3 报销业务
- 杨俊无需先存在差旅申请;
linked_travel_request_id可空。 - 提交仍须满足既有硬门禁:至少一条费用明细、至少一张已绑定且状态为
bound的真实票据、可匹配工作流并能解析审批人。 - 第一笔真实报销必须由杨俊本人操作;Codex 不代建生产报销、发票、付款或测试业务数据。
4.4 timer 与备份
- 使用现有
install-automatic-backup-timer.sh和install-warch3-ops-timer.sh,从活动部署现场解析并显式传入合同参数;不在任务文档中固化 Secret、宿主路径或完整账号。 - 重装后核对 4 个 service 的
BUILD_SHA与活动 server 一致,并确认对应 timers 为 enabled/active。 - 随后手工触发 daily 自动备份路径,验证源端 service 成功、ARM 批次完成且 dead-man/新鲜度检查通过。
- 新鲜异机恢复点是人员数据写入的前置条件,但不会用于回滚单个人员变更。
5. 失败与回退
- timer 重装或异机备份失败:不写杨俊数据,保留本地诊断并走既有脱敏群告警。
- dry-run 不满足
target=1 / active=1 / incomplete=0 / planned create=1 / conflicts=0 / skipped=0 / failed=0:不 apply,重新核对输入或生产现状。 - apply 失败:停止;按脚本结果诊断,不手工拼接残缺账号。
- apply 成功但主管写入失败:保留已创建的 OA 员工和企微绑定,不删除、不恢复整库;主管仍为空时不能提交报销,可安全重试同一主管接口。
- 主管写错:通过同一接口恢复写入前的
direct_manager_id,不恢复整库。 - 真实报销提交失败:保留草稿和真实票据状态,按返回的业务错误定位;不得通过扩权、代批或伪造数据绕过。
6. 隐私与审计
- 终端与任务证据只保留布尔值、计数、角色 slug、审计 action 和脱敏状态。
- 不输出手机号、企业邮箱、企微 userid、完整账号、通讯录原始行、票据内容、银行资料、Secret 或完整宿主路径。
- 账号导入与主管写入分别保留现有系统审计,确保每一步可独立追踪和撤销。
7. 不做的设计扩展
- 不新增导入 API、主管兜底规则、CEO 自审批能力或报销状态。
- 不启用 OA → 企微通讯录写回,不修改任何企微成员资料。
- 不创建法体、不补银行账号、不导入其余成员。
- 不把首次真实业务扩成管理员代办的生产自动化测试。