文件
hyb-oa/docs/需求-统一审批中心规约.md
T

59 KiB
原始文件 Blame 文件历史

需求 - 统一审批中心规约

版本:1.3 日期:2026-05-13 状态:模块级开发规约 上级事实源:海音达OA-MVP需求规格说明书

本规约细化 hyb-oa 审批中心和企业微信原生审批镜像的产品边界、角色权限、状态模型、异常规则、留痕要求和验收场景。WFOC 起,审批按主办方分层;DBWFOC 后边界进一步收窄:报销、财务、采购、合同和项目类审批继续由 OA 主办;请假、补卡、外出、加班等 HR/考勤员工日常审批优先由企业微信主办,OA 同步按域镜像并保留自建历史留存、人工接管和恢复回写能力。WMSG1 已验证企业微信应用消息和 Deeplink 回流,WAPC1 后审批镜像前置工作进入配置准备清单阶段,WAPC2 已提供请假/补卡只读 POC runner,WAPC2FLIVE 已自动生成请假/补卡 OA-POC 样件并复跑通过。WCBK1 已完成只读回调 URL 验证和真实审批事件确认,结论为 PASS_CALLBACK_EVENT_CONFIRMED。WEGOV1 后明确先利用企微成熟审批和考勤能力,同时由 OA 保存关键历史和外部关联键。WACP3R 已自动发现 OA-POC 请假/补卡模板并公网复跑到 PASS_WITH_FINDINGS:补偿拉取和详情读取可用,finding 是回调证据文件未持久化。WREAD1F 后已完成请假/补卡真机可读性确认:消息卡片、列表、详情页均可看清,远端报告 /app/artifacts/qa-flow/wecom-approval-readability-gate-20260519T133628Z/summary.json 为 PASS_READABLE;但同意按钮单击即通过,需在归档审计、提示或操作规程中处理。WADM1 已完成自建留存/镜像数据模型设计;WARCH1 已实现请假/补卡最小历史留存;WARCH2 已新增正式只读历史查询 API 和 PC/移动历史页。WAPPR1/WRULE1 后固定“单一组织规则,两个执行域”:OA 维护员工主管链、业务审批角色和管理员兜底事实,企业微信执行 HR/考勤审批,OA 只做归档和理论审批人校验;完整镜像、应急接管、恢复回写和 RuleOps 仍不能直接放行。后续审批相关开发必须先从本规约拆分 Issue CSV,再进入技术方案和代码实现。


1. 模块目标与边界

1.1 目标

  • hyb-oa 是财务审批、报销、采购、合同、项目和审计镜像中心。
  • HR/考勤员工日常审批优先复用企业微信原生审批;OA 同步审批单、审批历史、附件、状态回调和审计镜像。
  • OA 保存企微主办审批的完整外部关联键和必要业务摘要,用于历史查看、补偿拉取、审计和后续恢复。
  • PC、移动端和企业微信入口应能区分 OA 主办审批、企微主办审批镜像和 OA 应急接管单据。
  • 企业微信消息继续作为 OA 主办审批的提醒和 deeplink;企微主办审批在企业微信内完成,OA 负责镜像和恢复对账。
  • 企微不可用时,管理员可人工开启 oa_hr_emergency_mode_v1,临时由 OA 接管 HR/考勤应急审批;企微恢复后通过 wecom_recovery_writeback_v1 回写和对账。

1.2 适用对象

首批及后续默认纳入 OA 主办审批中心的正式审批包括:

  • 报销审批。
  • 采购审批。
  • 费用审批。
  • 合同审批、合同变更审批和合同归档相关审批。
  • 资产领用、归还、调拨、盘点中需要正式留痕的动作。
  • 后续新增财务、采购、合同、项目和高风险业务审批,除非另有明确产品决策,否则默认接入 OA 主办审批中心。

企业微信主办审批第一批包括:

  • 请假。
  • 补卡。
  • 外出。
  • 加班。
  • 与上述事项关联的假期余额和考勤解释。

OA 中既有请假、补卡、外出、加班能力转为历史只读、镜像展示和应急接管能力;正常情况下不再作为员工日常提交入口。

1.3 暂不做范围

  • 不接入飞书登录、飞书审批、飞书通知或飞书项目管理。
  • 首批不做复杂 BPM 设计器、自由拖拽流程、并行会签、条件分支可视化建模。
  • 首批不做跨公司多租户审批市场化配置。
  • 首批不做审批动作离线处理;移动端必须在线提交动作。
  • 不把企业微信 HR/考勤审批结果直接用于报销付款、财务复核或 AP 台账;财务动作必须在 OA 内完成。
  • 不把采购单、合同正文、报价、供应商资料、发票、银行回单或代账资料上传到企业微信原生审批或企业微信附件。
  • 不让 AI 直接改正式审批模板;wecom_ruleops_v1 只能先草拟和 dry-run,人工确认后才允许写入企微。

2. 角色与权限

角色 典型用户 可做动作 权限边界
申请人 普通员工、主管、财务、HR 创建草稿、提交、查看自己的单据、撤回允许撤回的单据、按退回意见修改后重提 只能编辑草稿、已退回、已驳回且规则允许重提的本人单据;当前不允许审批自己的待办;未来如需自审例外,必须另拆规则并强审计
审批人 主管、项目负责人、老板、被转审人 查看分配给自己的待办,通过、驳回、退回、转审、查看审批历史 只能处理当前分配给自己的任务;不能越权处理他人待办
财务 财务人员、财务主管 处理报销复核、付款标记、财务导出、重复发票例外审批中与财务相关的动作 不默认拥有系统管理权限;财务例外动作必须留痕
HR/行政 HR、行政负责人 在企业微信处理请假、补卡、外出、加班等 HR/考勤员工日常审批;在 OA 查看镜像、处理应急接管和恢复对账 不能绕过审批流直接改业务结果,必要修正必须审计
老板/总经理 公司负责人 处理大额、高风险或最终节点审批,查看公司级待办和摘要 操作仍需写入审批历史和审计日志
系统管理员 运维或后台系统负责人 配置角色、权限、企业微信入口、通知、基础字典、功能开关、应急模式和 RuleOps admin 只代表系统管理权限,不自动获得业务单据审批权;应急模式、回写和规则写入必须有审计

权限判定以服务端为准,前端按钮显隐只是体验优化,不作为授权依据。

2.1 权限与数据范围矩阵

角色 可查看范围 可审批范围 附件下载 导出 例外处理
申请人 本人发起、本人作为实际报销人、抄送给本人的单据 当前不可审批自己的待办;未来如需自审例外,必须另拆规则并强审计 草稿和本人单据附件;审批中及归档附件按业务权限展示 不允许批量导出 不允许
审批人 分配给自己的待办、已办和自己审批链上的单据 当前分配给自己的任务 可查看审批所需附件,下载动作需留痕 不允许财务级导出 可转审,不可财务例外
财务 报销、费用、付款、发票相关单据和财务导出范围 财务复核节点、重复发票例外节点、付款相关节点 可查看和下载财务复核所需附件,敏感附件下载留痕 可按权限导出财务台账 可处理重复发票、付款修正等财务例外
HR/行政 人员、部门、请假、补卡、外出、加班等行政范围 HR/行政复核节点 可查看行政审批所需附件 可导出行政审批统计,不能导出财务明细 可处理审批人停用、规则缺失等管理例外
老板/总经理 公司级摘要、大额或高风险审批、关键业务单据 最终审批节点或指定高风险节点 可查看决策所需附件,下载留痕 可查看公司级摘要,批量导出按配置控制 可审批高风险例外,但仍需记录原因
系统管理员 系统配置、日志、权限、集成状态 默认不具备业务审批权 技术排障需最小化授权并留痕 默认不导出业务数据 可做账号、规则、通知配置修复;业务数据修正需另走审计流程

数据范围以服务端权限和审计日志为准。任何导出、附件下载、例外处理都必须记录操作者、时间、对象和原因。

2.2 角色视图与动作裁剪

统一审批中心使用同一套 OA 审批数据、任务和历史记录,但 PC、移动和企业微信入口应按角色裁剪入口、摘要、动作和敏感信息。角色视图只影响展示和操作便利性,不改变服务端权限模型。

角色视图 重点入口与摘要 允许突出动作 不应展示或必须隐藏
员工视图 新建、草稿、审批中、退回修改、通知、我的申请 保存草稿、提交审批、撤回、按退回意见重提、查看本人状态 管理配置、全量人员、财务付款、他人待办审批动作
审批人视图 待处理、已处理、审批详情、附件/发票摘要、审批历史 通过、驳回、退回、转审、查看审批记录 无关员工列表、财务后处理、未分配给自己的审批按钮
财务视图 PC 端财务复核、付款状态、导出、重复票据例外;移动端只保留必要复核和查看 财务复核、付款标记、财务导出、重复发票例外处理 系统管理能力、非财务业务审批权、无审计的敏感附件下载
管理员视图 系统配置、账号、角色、组织、通知渠道、审计日志 配置修复、账号启停、角色分配、通知渠道测试、审计查询 业务审批按钮;除非同时具备正式业务角色且不是自审,不得处理业务待办
负责人视图 / CEO 视图 高额、高风险、例外待办,公司级摘要,审批效率和风险概览 处理分配给自己的最终审批或例外审批,查看高风险摘要 本人单据自审、仅凭 admin 权限处理业务、无配置依据的全量业务操作

移动端也遵循上述角色视图,但不为每个角色做完全不同的页面体系:同一移动 Shell、列表卡片、详情分区、顶部返回和吸底主操作框架下,按权限显示不同内容和动作。前端隐藏无权动作只是体验优化;服务端仍必须拒绝越权、自审和状态非法操作。

2.3 正式审批组织与角色映射

正式运行和 R5 真机验收按以下组织口径执行;实现不得把个人姓名硬编码到业务逻辑中,应通过员工、直属上级和角色配置落地。

人员 正式角色口径 配置要求 审批边界
majianyong 员工可见的直属主管 / manager 普通员工直属主管配置为 majianyong 处理普通员工低/中额单据和日常审批;本人申请不得自审
wangshunli 后台公司负责人 / ceo + admin 配置为 ceo 和 admin,不配置为普通 manager 处理大额、高风险、例外事项和 majianyong 本人申请;本人申请不得自审
专用测试员工 普通员工 / employee 直属主管配置为 majianyong 用于正式链路验收,不使用真实员工日常账号跑自动化

正式员工必须配置直属主管。缺直属主管、主管停用、主管链断裂或审批节点解析到申请人本人时,应阻断提交或阻断审批动作,并提示管理员修正组织或审批规则。不得用 admin 权限解释业务审批权,也不得用无条件升级 CEO 掩盖主数据错误。


3. 入口与任务视图

3.1 入口

入口 路径或位置 用途 要求
PC 审批待办 /workflow/tasks 审批人集中处理待办、已办、抄送或历史任务 应在 PC 主导航清晰可达
移动审批 /mobile/approvals 手机端处理待办和查看审批历史 应适配企业微信 WebView 和普通手机浏览器
业务详情页 报销、请假、采购、合同等详情页 从具体单据查看审批流和执行动作 状态、当前节点、历史记录必须与待办一致
企业微信消息 deeplink 到 OA 页面或企微原生审批 OA 主办审批回 OA,HR/考勤企微主办审批在企业微信处理 必须区分主办方,不把企微 HR 审批当作财务审批;OA 主办域附件不进入企微
Portal 待办摘要 /portal 或首页卡片 提醒当前待处理数量 点击后进入 /workflow/tasks 或对应详情页

3.2 任务列表要求

  • 待办列表至少展示:业务类型、业务编号、标题或摘要、申请人、金额或天数等关键值、当前节点、到达时间、状态。
  • 移动端列表应优先展示业务类型、编号、申请人、状态和主要金额/天数,不展示桌面宽表。
  • 已办或历史列表应能查看处理结果和处理时间,但首批不要求复杂筛选。
  • 待办数量、单据详情状态、审批历史必须一致。

4. 审批对象与字段

统一审批中心对所有业务单据抽象以下通用字段,具体业务可扩展自己的字段。

字段 含义 要求
business_type 业务类型,如报销、请假、采购、合同 必填,用于路由、权限和列表展示
business_id 业务单据主键 必填,与业务表关联
business_no 业务编号,如报销单号、采购单号 必填,OA 生成或校验唯一
title 审批摘要标题 必填,用于待办和通知
applicant_id 申请人 必填
department_id 申请人所属部门 可空但推荐保留
project_id 关联项目 业务需要时填写
amount 金额类摘要 报销、采购、费用、合同等需要
current_status 当前业务状态 必须与工作流状态同步
current_task_id 当前待办任务 审批中必须存在
submitted_at 提交时间 提交后必填
completed_at 审批完成时间 通过、驳回终止、撤回终止或完成时填写

4.5 审批规则配置矩阵

以下金额和天数是 10 人以下公司试运行建议值,不等于最终公司财务制度。正式上线前可由管理员按公司制度配置,后续实现不得把这些阈值硬编码在业务逻辑中。

业务类型 试运行阈值 默认审批链 财务/HR 复核 兜底审批人 撤回 转审
报销/费用 <=500 元 直属主管 无财务节点,财务可事后抽查 老板/总经理 审批完成前允许撤回 允许转给同级或上级审批人
报销/费用 500-3000 元 直属主管 财务复核 老板/总经理 财务复核前允许撤回 允许转给具备审批或财务权限的人
报销/费用 >3000 元 直属主管 -> 老板/总经理 财务复核 老板/总经理 老板审批前允许撤回 允许转审但不得绕过老板或财务节点
采购 <=1000 元 直属主管 视费用类型抽查 老板/总经理 审批完成前允许撤回 允许转给项目负责人或上级
采购 1000-5000 元 直属主管 -> 老板/总经理 视付款方式财务复核 老板/总经理 老板审批前允许撤回 允许转审但不得绕过老板节点
采购 >5000 元 直属主管 -> 老板/总经理 财务复核,建议关联合同或附件 老板/总经理 老板审批前允许撤回 允许转审但必须保留原因
请假 由企微模板配置 企业微信原生审批 按企微模板和公司制度 OA 应急时按管理员临时规则 按企微能力或 OA 应急规则 企微正常时在企微处理,OA 只同步镜像
补卡 由企微模板配置 企业微信原生审批 按企微模板和公司制度 OA 应急时按管理员临时规则 按企微能力或 OA 应急规则 企微正常时在企微处理,OA 只同步镜像
外出 由企微模板配置 企业微信原生审批 按企微模板和公司制度 OA 应急时按管理员临时规则 按企微能力或 OA 应急规则 企微正常时在企微处理,OA 只同步镜像
加班 由企微模板配置 企业微信原生审批 按企微模板和公司制度 OA 应急时按管理员临时规则 按企微能力或 OA 应急规则 企微正常时在企微处理,OA 只同步镜像
合同 所有 负责人主管 -> 老板/总经理 财务按金额或付款条款复核 老板/总经理 老板审批前允许撤回 允许转审但不得绕过老板节点

规则匹配优先级为:业务类型 -> 金额或天数阈值 -> 项目/部门特殊规则 -> 默认规则。若找不到审批人、缺直属主管、主管链断裂、审批人停用或节点解析为申请人本人,提交必须阻断并提示管理员修正组织或审批规则,不得生成半截流程。

大额、高风险或例外事项默认进入老板/总经理节点;当前试运行最小集合包括:重复发票例外、预算或费用标准超限、缺必要附件仍需例外处理、涉密或重点项目、合同/采购高金额事项。具体阈值和例外条件必须通过审批规则配置,不得硬编码到个人或前端按钮。


5. 状态模型

5.1 通用状态

状态 含义 允许的主要动作
草稿 申请人正在编辑,未进入审批 保存、提交、删除草稿
审批中 已提交,存在当前审批任务 审批人通过、驳回、退回、转审;申请人在规则允许时撤回
已通过 所有审批节点通过,进入业务后处理 财务付款、合同归档、考勤生效等业务动作
已驳回 审批人否决,流程终止或允许复制重提 查看历史、按业务规则重新发起
已退回 审批人要求申请人修改 申请人修改后重提、撤回
已撤回 申请人撤回,流程终止 查看历史、按业务规则复制重提
已完成 审批通过后的业务处理完成 查看、归档、导出
已付款 报销或费用类单据已付款 查看、导出;普通用户不可修改

已付款 是报销、费用等财务类业务的完成状态之一;非财务业务可使用 已完成。

5.2 状态转换规则

  • 草稿只能由申请人或授权代填人提交。
  • 提交成功后生成工作流实例、当前节点和第一条待办。
  • 当前审批人通过后,系统按规则推进到下一节点;无下一节点时进入 已通过。
  • 驳回默认终止当前流程,是否允许复制重提由业务模块决定。
  • 退回回到申请人修改态,重提后应保留同一业务单号和完整历史。
  • 撤回只允许在流程未完成且规则允许时发生。
  • 转审只改变当前任务处理人,不改变业务单据申请人。
  • 已完成、已付款、已归档类状态原则上不允许普通用户修改核心字段。

5.3 状态流转表

当前状态 动作 操作者 目标状态 是否保留单号 是否生成新版本 是否通知
草稿 保存 申请人 草稿 是 否 否
草稿 提交 申请人 审批中 是 是,记录提交版本 是,通知首个审批人
审批中 通过但还有下一节点 当前审批人 审批中 是 否 是,通知下一审批人
审批中 最终通过 当前审批人 已通过 是 否 是,通知申请人和后处理角色
审批中 驳回 当前审批人 已驳回 是 否 是,通知申请人
审批中 退回 当前审批人 已退回 是 是,等待申请人修改 是,通知申请人
已退回 修改后重提 申请人 审批中 是 是,记录重提版本 是,通知首个审批人
审批中 撤回 申请人 已撤回 是 否 是,通知当前审批人
审批中 转审 当前审批人 审批中 是 否 是,通知被转审人
已通过 财务付款或业务归档 财务或业务负责人 已付款或已完成 是 否 是,通知申请人
已完成/已付款 管理修正 授权管理员或财务主管 保持已完成/已付款并追加修正记录 是 是,记录修正版本 按敏感级别通知

撤回、退回、驳回后的重新发起策略由业务模块决定;报销场景默认保留原单号用于退回重提,驳回后复制新单据时应生成新流程并关联原单据。


6. 审批动作

动作 发起人 前置条件 结果与留痕
保存草稿 申请人 有创建权限 写入业务草稿,不生成审批任务
提交 申请人 必填字段、附件、金额、发票等业务校验通过 生成工作流实例、待办、提交历史和通知
通过 当前审批人 任务未处理且权限匹配 当前任务完成,进入下一节点或业务通过
驳回 当前审批人 必填驳回原因 流程终止或进入业务定义的驳回态
退回 当前审批人 必填退回原因 任务回到申请人修改态,保留历史
撤回 申请人 流程未完成且业务允许撤回 流程终止或回到草稿,写入撤回原因
转审 当前审批人 目标人具备处理资格,未超过转审限制 当前任务转给目标人,记录转审链路和原因
批量审批 审批人 多个任务均可被当前人处理 每个任务独立校验、独立成功或失败
查看历史 相关人员 对单据有查看权限 展示提交、审批、退回、转审、通知和关键业务动作

批量审批不得绕过单条任务的权限、状态和业务校验。

审批动作按钮使用短文案 通过 / 驳回 / 退回,不得在按钮内堆叠长说明。PC 和移动端执行这些动作前必须二次确认,在确认弹窗中解释后果:通过会进入下一审批节点或完成审批并写入历史;驳回会终止当前流程或进入驳回态,申请人通常需要复制或重新发起;退回会回到申请人修改态,保留原单号和审批历史,申请人修改后可重新提交。驳回和退回都必须填写可理解意见。

R7E 后,全站高风险操作沿用同一确认模式:提交审批、撤回、删除、归档、启用/停用、批量处理、财务复核/付款、重复票据例外、敏感数据导出和通知测试/重发都必须使用 OA 内二次确认弹窗;普通保存草稿、筛选、分页、查看、预览和取消编辑不强制确认,避免确认疲劳。PC 端确认由 Playwright 自动化覆盖,企业微信真机只保留消息、免登录、WebView 文件选择器等真实环境差异项。

6.1 自审与转审约束

  • 自审默认禁止,不因申请人同时拥有 admin、manager、ceo、finance 或其他角色而放开。
  • 自审识别至少覆盖:工作流提交人、报销实际报销人、报销提交人、请假人、采购申请人、采购提交人、差旅申请人和差旅提交人。
  • 批量审批必须逐条执行自审校验;自审任务失败不应影响其他合法任务处理。
  • 转审目标必须具备对应业务审批权限,不能是申请人本人,不能是仅具备 admin 的系统管理员。
  • 转审不能绕过规则定义的必经老板/总经理、财务或 HR/行政节点;需要例外时必须另走明确改派或规则调整流程并留痕。
  • 若老板/总经理本人提交的单据触发老板/总经理节点,默认阻断或进入明确配置的非本人兜底审批人;本规约不开放自审例外。

6.2 WF8 转审扩展设计

WF8 阶段只做轻量转审扩展,不进入复杂 BPM、审批设计器、并行会签或自由流程编排。转审的定义是“当前待办任务处理人变更”,不是业务单据申请人变更,也不是审批规则永久改写。

成熟 BPM 和任务中心通常把流程定义、候选处理人和当前任务分配分开管理。WF8 沿用这一思路:规则仍决定必经节点,转审只在当前节点内调整 assignee_id,并通过历史和通知留痕。

适用范围:

  • 首批覆盖报销、请假、采购三类已接入统一审批中心的待办。
  • 合同、差旅、资产等后续业务沿用同一原则,但必须另走对应连续 Issue 验收。
  • OA 主办审批通过企业微信通知和 deeplink 回 OA;HR/考勤企微主办审批允许在企业微信原生审批中完成转审或流转,OA 同步最终详情。

发起人规则:

  • 只有当前 pending 待办的实际可处理人可以发起转审;有效委托场景下,实际处理人必须写入委托相关 payload。
  • admin 单角色不能代替业务审批人发起转审。
  • 已处理、已撤回、已取消、已完成或孤立待办不得转审。

接收人规则:

  • 接收人必须是 active 员工。
  • 接收人必须具备当前业务类型对应的审批权限:报销使用 expense.approve,请假使用 leave.approve,采购使用 procurement.approve。
  • 接收人不能是申请人、实际报销人、提交人或当前动作人本人。
  • 仅具备 admin 的系统管理员不能作为业务转审接收人。
  • 不得通过转审绕过老板/总经理、财务、HR/行政等规则定义的必经节点。

状态和历史规则:

  • 转审保持同一个 workflow instance、同一个 workflow task 和同一个当前审批节点,只更新当前任务处理人。
  • 转审不改变报销、请假、采购的业务状态,不触发财务付款、预算占用确认、ERP 同步、考勤生效或附件归档。
  • 每次转审必须写 workflow_history,至少包含原处理人、目标处理人、原因、转审次数和委托上下文。
  • 报销既有 approval_transfers 可作为兼容审计表继续保留;请假和采购首批以 workflow_history 为事实源,后续如需结构化转审表必须另写迁移方案。
  • 转审成功后通知目标审批人;通知失败不回滚主业务,但必须可追溯。

并发和重复规则:

  • 同一任务最多转审 3 次,超过后阻断并提示选择管理员处理或规则修正。
  • 服务端必须在事务内锁定当前任务,防止两个窗口同时转审、审批或退回导致重复结果。
  • 转审不得新建并行待办,不得留下原审批人可继续处理的 pending 任务。
  • 转审后原审批人再次打开旧页面时,应看到任务已变化或无权处理提示。

三类业务副作用边界:

业务 转审允许影响 不允许影响
报销 当前审批人、审批历史、通知目标 发票绑定、附件、财务付款状态、重复票据例外、OCR 状态
请假 当前审批人、审批历史、通知目标 请假天数、余额预占、团队状态、考勤生效结果
采购 当前审批人、审批历史、通知目标 采购明细、附件、预算预检结果、ERP 同步、PO/合同归档

回滚和修正路径:

  • 转审目标选错但任务仍 pending 时,由当前合法处理人再次转审回正确处理人,并填写修正原因。
  • 目标人停用、离职或权限被回收时,不直接改数据库;由管理员按 ORG8 账号与权限治理流程确认后,通过受审计的改派或规则修正路径处理。
  • 若代码实现引入回归,优先回滚 WF8 代码补丁并复跑 server/scripts/regression-workflow-actions.sh;已产生的历史记录不删除,只追加修正说明。

WF8-3、WF8-4、WF8-5 实现前必须基于本设计给技术方案;实现后必须运行转审单测、相关业务流回归,并启用 workflow reviewer 检查状态机、权限、通知和漏测项。


7. 异常规则

异常 处理规则 用户提示
无审批人 提交时阻断,不生成半截流程;管理员可修正规则后重试 “当前审批规则未找到审批人,请联系管理员”
自审 申请人、实际报销人或提交人命中当前审批人时阻断;管理员身份不能绕过 “自己的申请不能审批,请等待下一审批人处理”
系统管理员无业务审批角色 仅有 admin 权限时不能处理业务审批;需配置 manager、ceo、finance、hr 等正式业务角色 “系统管理员不自动获得业务审批权,请配置正式审批角色后处理”
权限不足 服务端拒绝,记录必要安全日志 “无权处理该审批任务”
任务已处理 并发点击或重复提交时返回当前最新状态 “该任务已处理,请刷新查看最新结果”
并发审批 以服务端事务和任务版本为准,只允许一个处理结果生效 “处理失败,任务状态已变化”
转审超限 超过次数、转给无权限人员或形成循环时阻断 “无法转审给该人员,请选择具备审批权限的人”
审批人离职或停用 待办不能继续由停用账号处理;管理员按规则改派或转审 “当前审批人不可用,请联系管理员处理”
业务单据被删除或归档 不允许继续处理孤立待办 “关联单据不可处理,请刷新或联系管理员”
通知发送失败 不阻断主业务,进入可重试状态 业务页面不报错;管理员可在通知日志查看

8. 留痕与一致性

8.1 必须留痕的记录

  • 工作流历史:提交、通过、驳回、退回、撤回、转审、批量审批结果。
  • 审计日志:权限变更、审批规则变更、管理员改派、敏感附件查看、财务例外动作。
  • 通知记录:发送渠道、接收人、发送状态、失败原因、重试次数、deeplink。
  • 业务状态记录:业务单据状态与工作流状态变更必须能追溯。

8.2 一致性要求

  • 审批动作成功后,业务单据状态、当前任务、审批历史必须在同一事务或等效一致性边界内更新。
  • 通知失败不回滚审批动作,但必须可重试。
  • 同一任务不能出现两个最终处理结果。
  • 业务详情页展示的审批历史与 /workflow/tasks 的任务状态必须一致。

9. 企业微信边界

  • 企业微信自建应用只作为 海音达工作台 手机入口。
  • 企业微信个人应用消息是正式审批待办提醒的首选 IM 通道;群机器人和 mock 只允许作为运维或自动化补充证据。
  • 企业微信消息只发送脱敏提醒:标题、业务编号、状态、处理入口。
  • 企业微信 deeplink 必须指向 OA 审批页或业务详情页。
  • 用户点击消息后,在 OA 内查看详情并执行审批动作。
  • 企业微信原生审批参与 HR/考勤员工日常审批正式流程,OA 通过 wecom_attendance_approval_mirror_v1 同步为可查询、可导出、可审计的镜像记录;该命名承接旧口径 wecom_native_approval_mirror_v1。报销、财务、采购、合同和项目类 OA 主办审批仍不得在企业微信原生审批中替代完成。
  • 采购单附件、合同正文、报价、供应商资料、发票、银行回单、代账资料和其他高敏附件不进入企业微信原生审批或企业微信附件;企业微信只做提醒、deeplink 和免登录回流。
  • 按域镜像是默认规则:企微主办 HR/考勤域镜像到 OA;OA 主办采购、合同、项目、财务和报销域不反向全量镜像到企微。
  • WFDG 后,审批相关页面和接口必须区分 OA 主办、企微镜像 和 OA 应急接管;企微镜像不得被误用为 OA 日常新建入口,OA 应急接管单据必须带 EMERGENCY 并进入恢复回写队列。
  • WAPI/WRRA/WOUA-FIX/WAPC1/WAPC2/WPROC1/WEGOV1 后,审批相关运行时迁移必须先读 企微优先开发路线图 和 企微 API 能力目录,按 wecom_hr_master_sync_v1 -> runtime_first_wecom_enablement -> WOUA-FIX / WECOM-RUNTIME-READY-V1 -> WAPC1 审批配置准备 -> WAPC2 请假/补卡只读 POC -> WAPC2F 自动生成 POC 样件 -> WAPC2FLIVE live 创建与 WAPC2 自动复跑 -> WCBK1 回调只读 POC -> WEGOV1 企微主办治理与自建留存路线修正 -> WACP3/WACP3R 补偿拉取 POC -> WREAD1 审批可读性与误审批防护门禁 -> WADM1 自建留存/镜像数据模型设计 -> WARCH1 最小自建历史留存实现 -> WARCH2 正式只读历史查询 -> WROAD2+OPS 受控上线与每日巡检 -> WARCH3 归档稳定化自动巡检 -> WCHECK1 打卡摘要留存 -> WEXT1 外出/加班 dry-run -> WOPS1 巡检告警降噪 -> WROAD2-CLOSEOUT 三天验收 -> WROAD2-BIZ1 三天业务冒烟 -> WAPPR1 审批规则规范化 -> WRULE1 审批链校验器 POC -> WAUTO1 自动证据汇总 -> WEXT1LD 外出/加班 live 前 dry-run -> WFULLSMOKE1 三天全域最终目标测试 -> WROUTE2 测试号收口到最小镜像路线锁定 -> WTCLOSE2 测试号最终收口与证据复核 -> WTCLOSE2F 远端可信 IP 执行口径修正 -> WEXT1-LIVE 外出/加班测试号 live POC -> 四类测试号证据和审批规则门禁通过后问答 WREAL1 小范围真实试用(首批 1 名真实员工 + 1 名审批人/管理员观察) -> wecom_attendance_approval_mirror_v1 最小完整镜像 -> oa_hr_emergency_mode_v1 -> wecom_recovery_writeback_v1 的顺序拆单功能 Issue CSV;WOUA-FIX 只收口了用户一致性测试账号差异和处理决策,WRV1/WRA1/WMSG1 只验证入口、OAuth/绑定、脱敏消息、deeplink、通讯录、人事助手、打卡只读主链路和真实消息回流。WAPC1 只固化审批配置准备清单;WAPC2 只读模板详情和低风险 sp_no 审批详情;WAPC2FLIVE 只生成 OA-POC 低风险测试样件并自动复跑只读 POC;WCBK1 只证明真实审批状态回调可验签、可解密、可脱敏留证;WACP3R 只证明补偿拉取和详情读取可用,并发现回调证据文件未持久化;WEGOV1 只修正混合主办、自建留存和测试治理口径;WREAD1 只证明请假/补卡当前样例可读;WADM1 只完成模型设计;WARCH1 已实现请假/补卡最小历史留存;WARCH2 只提供只读查询 API 和历史页;WEXT1 只完成外出/加班 dry-run;WROAD2-BIZ1 只补充测试账号人工业务冒烟清单;WAPPR1 将申请人任意选择审批人列为真实试用前阻断 finding;WRULE1 只校验已归档审批链;WAUTO1 只做自动证据汇总,WEXT1LD 只做 live 前 dry-run,WFULLSMOKE1 只做全域主路径总控;WROUTE2 只锁定路线,WTCLOSE2 只做最终自动收口,不授权写入;WEXT1-LIVE 写入前必须另建合同并再次人工确认。完整企微审批镜像必须等 WREAL1 通过后再规划,应急接管和恢复回写仍后置,不得用 WARCH1/WARCH2 或测试号证据直接放行。
  • WRV1/WRA1 runner npm run check:wecom-runtime-ready 中的审批模板、测试 sp_no 和真实回调检查只允许输出 NEEDS_CONFIG;这类缺口不阻断运行优先主链路的 PASS_WITH_CONFIG_GAPS,但必须阻断 wecom_attendance_approval_mirror_v1、应急恢复回写和 RuleOps。WECOM_CHECKIN_SYNC_ENABLED 只控制正式考勤同步批次,不阻断 QA-only 打卡只读能力探测。
  • WMSG1 已证明企业微信应用消息可达和 Deeplink 可进入 OA 通知页;该证据只清除通知链路,不清除审批模板、测试 sp_no 或真实回调前置。WAPC1 固化配置准备清单后,WAPC2 先提供请假/补卡模板详情和低风险审批详情只读 POC;WPROC1 后优先用 WAPC2F 自动生成 POC 样件,不默认要求人工手动创建模板或测试单。人工介入限于写入批准、密钥/回调配置、企微后台无法 API 化配置、真机确认和风险拍板。
  • 后续企微审批同步的 POC 必须输出 CAN_REUSE_NOW、NEEDS_CONFIG、NEEDS_API_POC、KEEP_OA_PRIMARY、NOT_SUPPORTED_BY_API,缺模板、回调、Secret 或权限时记录 SKIP/BLOCKED_BY_EXTERNAL_CONFIG。
  • 若企业微信返回 invaliduser、unlicenseduser、不可见范围或权限类错误,业务提交和审批动作不应回滚,但通知记录必须可审计、可重试,并提示管理员修正企业微信应用可见范围或账号绑定。
  • 真机验收以企业微信手机端收到应用消息并可点击回流为准;系统级弹窗是否出现受客户端通知权限影响,不作为 OA 通知链路硬门槛。

9.1 WAPC1 企微审批配置准备

WAPC1 是进入 wecom_attendance_approval_mirror_v1 前的配置准备清单,不是审批镜像实现。

首批企业微信原生审批模板:

  • 请假。
  • 补卡。
  • 外出。
  • 加班。

每个模板至少准备:

  • 模板 ID。
  • 适用范围、可见范围和所属自建应用权限。
  • 字段项、字段类型、审批人规则和状态流转边界。
  • 企微侧转审、撤回、退回、附件和抄送能力边界。

后续 POC 必须验证:

  • POST /cgi-bin/oa/gettemplatedetail 可读取模板详情,Secret 固定为 WECOM_AGENT_SECRET。
  • POST /cgi-bin/oa/getapprovaldetail 可读取低风险测试 sp_no 的审批详情,测试单不得包含采购、合同、报销、发票、银行回单、高敏附件或真实敏感业务资料。
  • 真实回调 URL 可被企业微信访问,Token 与 EncodingAESKey 只配置在部署环境,不写入仓库、文档或 Issue。
  • 回调验签、解密、幂等键、企业微信重试语义、失败重试和补偿拉取方案明确。
  • 批量获取审批单号作为补偿拉取候选,先标记 NEEDS_API_POC。

9.2 WAPC2 企微审批只读 POC

WAPC2 是 WAPC1 后的首个审批只读 POC,范围只包括请假和补卡,不是 wecom_attendance_approval_mirror_v1。

  • 新增 QA-only runner npm run check:wecom-approval-poc,默认不写 OA/企微数据,不接真实回调。
  • 请假模板使用 --template=leave:<id>,补卡模板使用 --template=missed_punch:<id>。
  • 请假低风险测试单使用 --sp-no=leave:<sp_no>,补卡低风险测试单使用 --sp-no=missed_punch:<sp_no>。
  • gettemplatedetail 和 getapprovaldetail 均固定使用 WECOM_AGENT_SECRET,不得尝试通讯录、打卡或历史 HR assistant Secret。
  • 报告只记录脱敏模板 ID/sp_no 前缀、字段类型计数、审批节点计数和状态摘要;不得输出表单值、附件、评论、完整 sp_no 或原始 payload。
  • 缺模板 ID 或测试单号时结论为 PARTIAL_APPROVAL_POC_NEEDS_CONFIG;权限、可信 IP、可见范围或 Secret 阻断时结论为 SKIP/BLOCKED_BY_EXTERNAL_CONFIG。

9.3 WAPC2F 自动生成 POC 样件

WAPC2F 是 WAPC2 后的自动化优先补缺阶段,目标是尽量用 QA-only runner 自动创建 OA-POC 请假/补卡测试模板和低风险测试审批单,再自动复跑 WAPC2。它不是正式模板配置、不是真实业务审批,也不是镜像实现。当前已新增 npm run check:wecom-approval-fixtures 并完成公网 dry-run,报告 /app/artifacts/qa-flow/wecom-approval-fixtures-20260519T045001Z/summary.json 为 PASS_FIXTURE_DRY_RUN_READY。WAPC2FLIVE 已在用户批准后修正 create_template payload,创建 OA-POC 请假/补卡测试模板和低风险测试审批单,报告 /app/artifacts/qa-flow/wecom-approval-fixtures-20260519T053400Z/summary.json 为 PASS_FIXTURE_CREATED,并自动复跑 WAPC2 得到 PASS_APPROVAL_POC;测试模板和审批记录保留审计,不自动删除。

  • 默认申请人固定 SMOKE002,审批人固定 SMOKE101。
  • 预检两者必须 active、已绑定企微、可见、不是同一 OA 员工、不是同一企微 userid。
  • 自审硬阻断,不因 admin、manager、ceo、finance 或其他角色放开。
  • 如果 SMOKE101 不可用,不自动换成 HYD000007 或其他人员;必须返回配置缺口并用问答方式确认新链路。
  • live 写入必须有显式 CLI 参数 --live --create-templates --submit-test-approvals 和单次进程环境变量 WECOM_APPROVAL_FIXTURE_WRITE=1,默认 dry-run 不获取写入 token、不调用企微写接口。
  • 报告只保存脱敏模板 ID/sp_no 前缀、计数、状态和错误分类,不保存完整 sp_no、表单值、附件、评论、完整 userid、Secret、token 或原始 payload。

9.3.1 WAPPR1 企微审批规则规范化门禁

WAPPR1 承接 WROAD2 期间发现的补卡申请仍需申请人手动选择审批人风险。企微主办不等于放开自由流;HR/考勤审批进入真实试用前,必须先证明审批人规则自动化、非自审且可审计。

  • 测试模板固定为 SMOKE002 -> SMOKE101,申请人不得选择自己,SMOKE101 不可用时不自动换人。
  • 公司不到 10 人时,正式请假、补卡、外出、加班模板采用一层直属主管或指定审批角色自动带出审批人,不允许申请人任意选择审批人。
  • 审批人缺失、停用、未绑定企微、不可见、主管链断裂或命中申请人本人时,必须由管理员兜底或阻断提交;若只能手选审批人,则阻断进入真实试用。
  • 官方 API 边界:gettemplatedetail 只返回模板控件,getapprovaldetail 只返回已提交审批单的实际审批节点和审批人,均不能只读证明申请页是否允许手选或修改审批人;applyevent 的 use_template_approver=1 属于写入型验证,且不适合作为补卡等模板的通用只读门禁。
  • WAPPR1 验收必须由三类证据组合:管理员在企微后台确认无“申请人自选”节点;SMOKE002 真机提交页确认审批人自动带出且不能任意改人;提交后用 getapprovaldetail 校验实际审批人为 SMOKE101 且无自审。
  • 2026-05-21 人工门禁结论:测试员工直属上级已设置为测试主管,用户真机确认请假、补卡、外出、加班提交页均自动带出测试主管,且申请人不能删除、改人或新增审批人;四类模板均按 A / PASS_APPROVER_RULES_READY 记录。
  • 结论按模板分别记录:PASS_APPROVER_RULES_READY、PASS_WITH_TEMPLATE_ADJUSTMENTS、FAIL_KEEP_OA_PRIMARY_FOR_THIS_TEMPLATE 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG。
  • A/B/C/D 人工门禁口径不变:只有 A 可作为规则门禁通过条件;B、C、D 均阻断 WEXT1-LIVE、WREAL1 和后续 wecom_attendance_approval_mirror_v1。
  • 如果企微模板能力或后台配置暂时无法做到自动审批人规则,对应模板继续保持测试账号 POC 或 OA 主办,不进入 WREAL1 真实员工试用。

9.3.2 WRULE1 企微 HR/考勤审批链校验器 POC

WRULE1 不新造 HR/考勤审批引擎,也不读取企微后台规则配置。它只在 WAPPR1 人工门禁基础上,用 OA 已归档的企微审批详情和 OA 组织事实源自动校验“理论审批人”和“实际审批链”是否一致,防止单规则双域变成两套规则。

  • runner 为 npm run check:wecom-approval-rule-validator;默认只读 OA DB,不调用企业微信 API,不读取 Secret,不写 OA 或企业微信业务数据。
  • 上游审批详情仍由 WARCH1/WROAD2 补偿归档链路提供,固定使用 WECOM_AGENT_SECRET,不得靠通讯录、打卡或历史 HR assistant Secret fallback。
  • 理论审批人计算顺序为:申请人的有效直属主管、配置的业务审批角色、管理员兜底。直属主管或角色审批人必须 active、已绑定企微且不是申请人本人。
  • 管理员兜底只允许作为可解释异常,输出 PASS_WITH_ADMIN_FALLBACK;它不能把 admin 权限解释成普通业务审批权。
  • 实际审批人为申请人本人时输出 FAIL_SELF_APPROVAL;实际审批人不在 OA 理论候选内时输出 FAIL_APPROVER_MISMATCH;WAPPR1 手工门禁 B/C 时输出 FAIL_APPLICANT_CAN_CHOOSE。
  • 未传 --manual-gate=<template>:A/B/C/D 时输出 PAUSED_MANUAL_CONFIRMATION,表示缺少后台人工确认或真机提交页证据,不得把实际审批链匹配误读为模板规则已合规。
  • 结论限定为 PASS_RULE_MATCH、PASS_WITH_ADMIN_FALLBACK、FAIL_APPLICANT_CAN_CHOOSE、FAIL_SELF_APPROVAL、FAIL_APPROVER_MISMATCH、PAUSED_MANUAL_CONFIRMATION 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG。
  • 报告只输出审批类型、计数、脱敏 sp_no/template/employee 前缀和 finding 类型,不输出完整 userid、完整 template_id、完整 sp_no、手机号、邮箱、token、Secret、表单值、附件、评论或原始 payload。
  • PASS_RULE_MATCH 或可解释 PASS_WITH_ADMIN_FALLBACK 只是进入测试号收口的自动证据之一;四类模板仍必须先由 WAPPR1 人工确认 A,才能进入 WEXT1-LIVE、WREAL1 和最小完整镜像。

9.3.3 WTCLOSE2 测试号最终收口与证据复核

WTCLOSE2 是 WEXT1-LIVE 前的最后自动收口。它复跑并汇总 WAUTO1、WFULLSMOKE1、外出/加班 dry-run 和 WRULE1 证据,确认测试号链路是否可解释通过;它不写企业微信、不创建外出/加班模板或审批单、不启用真实员工。

  • 企业微信 API 受可信 IP 限制,WTCLOSE2 真实运行必须在部署服务器执行;runner 为 bash scripts/qa/run-wecom-test-account-final-closeout.sh --remote,由 SSH 到部署服务器并在 server 容器中生成 artifacts/qa-flow/wecom-test-account-final-closeout-*/summary.json。
  • 本地直接执行 WTCLOSE2 脚本默认拒绝跑企微链路;本地只允许做 bash -n、合同、文档和静态门禁,不得把本地缺 env/DB 输出当作企微业务阻断证据。
  • WFULLSMOKE1 在 WTCLOSE2 中必须以 WFULLSMOKE_ALLOW_PUBLIC_WRITES=0 运行,不新增 OA 测试业务数据。
  • WRULE1 固定传入 --manual-gate=all:A,但仍只代表已提交审批链校验,不替代 WAPPR1 人工后台和真机门禁。
  • 外出/加班步骤只执行 dry-run,不设置 WECOM_APPROVAL_FIXTURE_WRITE=1,不带 --live、--create-templates 或 --submit-test-approvals。
  • 结论限定为 PASS_TEST_ACCOUNT_CLOSEOUT_READY、PASS_WITH_FINDINGS、PAUSED_MANUAL_CONFIRMATION 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG。
  • WTCLOSE2 可解释通过后只能进入 WEXT1-LIVE 问答;live 创建、真实员工试用和最小完整镜像仍需各自独立合同和人工批准。

9.4 WEGOV1 / WACP3 / WREAD1 / WADM1 / WARCH1 前置门禁

在 wecom_attendance_approval_mirror_v1 前必须补齐治理、POC、真机和数据模型门禁:

  • WCBK1 回调只读 POC:已新增只读 GET/POST /api/wecom/approval/callback 和 npm run check:wecom-approval-callback-poc。公网 synthetic 验签、解密和解析通过后,部署环境完成回调配置并达到 PASS_CALLBACK_URL_VERIFIED;SMOKE101 随后处理现有 OA-POC 补卡测试单触发真实事件,复跑结论 PASS_CALLBACK_EVENT_CONFIRMED,报告只保存脱敏事件证据。
  • WEGOV1 企微主办治理与自建留存路线修正:固定企微主办域、OA 主办域、OA 留存域和 OA 应急域;明确企业微信没有完整 sandbox 假设,默认使用受控测试域和自动化 runner。
  • WACP3 补偿拉取 POC:已新增 check:wecom-approval-compensation-poc 和 getapprovalinfo 只读封装;WACP3R 公网复跑为 PASS_WITH_FINDINGS,已按 SMOKE002 creator 自动发现请假/补卡 OA-POC 模板并拉取审批详情。当时 finding 为回调证据文件未持久化,已由 WADM1 设计和 WARCH1 DB 回调事件入库承接。
  • WREAD1 审批可读性与误审批防护门禁:已新增 check:wecom-approval-readability-gate 只读 runner,并在 WREAD1F 新样例后完成真机确认。公网人工结果报告 /app/artifacts/qa-flow/wecom-approval-readability-gate-20260519T133628Z/summary.json 为 PASS_READABLE:请假和补卡消息卡片、审批列表、详情页足够看清;驳回有二次确认,同意单击即通过。后续不要求回退 OA 主办;WARCH1 已在归档审计中保留动作来源和补偿对账,正式历史页/操作规程仍需继续提示该风险。
  • WADM1 自建留存/镜像数据模型设计:已完成字段、状态机、幂等键、索引、隐私保留、审计和迁移回滚方案设计。
  • WARCH1 最小自建历史留存实现:已新增请假/补卡审批留存表、回调事件表、补偿 run/item/finding、补偿入库双开关和 QA-only 离线读取 runner;先证明企微不可用时可查看已保存历史,再进入完整镜像增强。
  • WARCH2 正式只读历史查询:已新增只读查询 API 和 PC/移动历史页;查询只读 OA DB,不调用企微 API,不读取企微 Secret;普通员工、主管和 HR/admin/* 使用分层权限,申请人未映射和 callback-only 记录默认只允许 HR/admin/* 查看;页面不提供审批按钮或待办语义。

9.4.1 WADM1 自建审批留存模型

WADM1 只做模型设计。WARCH1 已在单独合同中创建最小迁移和写入路径,范围仍限定请假/补卡历史留存。

企微主办审批进入 OA 自建留存时,建议按以下模型拆分:

设计模型 职责 必要字段
WecomApprovalArchive 审批单主表,表示一条企微审批在 OA 的历史事实 sp_no、template_id、template_type、规范化状态、企微原状态码、申请人 OA 员工、申请人企微 userid、申请/完成/更新时间、最后来源、风险标记
WecomApprovalParticipant 申请人、审批人、抄送人、节点参与人快照 sp_no、角色、节点序号、企微 userid、OA 员工映射、是否当前节点、是否映射失败
WecomApprovalAction 通过、驳回、撤回、转交、系统状态变化等动作历史 sp_no、动作类型、操作者、动作时间、节点序号、意见摘要、来源和幂等键
WecomApprovalFieldSummary 表单字段规范化摘要 字段 key、字段名、字段类型、规范化值、敏感级别、是否可展示
WecomApprovalAttachmentSummary 低风险附件摘要和外部引用 附件数量、类型、外部引用摘要、是否下载、敏感级别
WecomApprovalCallbackEvent 企微回调事件持久证据 approval_archive_id、完整 sp_no、完整 template_id、事件类型、规范化状态、接收时间、企微事件时间、处理结果、幂等键、摘要 digest;日志和报告只输出脱敏前缀
WecomApprovalCompensationRun / WecomApprovalCompensationItem 补偿拉取运行和逐单详情证据 时间窗口、模板过滤、游标、计数、错误分类、sp_no 关联、详情拉取状态
WecomApprovalReconcileFinding 回调与补偿对账差异 漏回调、重复回调、状态不一致、样例缺失、权限阻断和解释状态

状态机统一为 pending、approved、rejected、revoked、terminated、changed、unknown、sync_failed。同一 sp_no 采用幂等 upsert,动作历史只追加不删除;若回调和补偿拉取状态冲突,主表不静默覆盖为成功,而是写入 WecomApprovalReconcileFinding。

回调与补偿合并规则:

  • DB 业务表必须保存完整 sp_no、template_id、企微 userid 和 approval_archive_id,用于稳定关联和补偿恢复;脱敏只发生在日志、报告、Issue、文档、默认导出和普通 UI 摘要。
  • getapprovaldetail 的详情快照是业务状态的最终校准来源;回调是低延迟事件来源。补偿拉取成功拉到详情后,可以修正主表状态,但必须保留原回调事件和动作历史。
  • 主表维护 status_observed_at、last_source、last_detail_digest。新事件只有在 observed_at 晚于当前状态时间,或详情 digest 变化时才能推进主状态;旧的非终态事件不得覆盖较新的终态。
  • 终态 approved、rejected、revoked、terminated 不被较旧的 pending 或 unknown 覆盖;若企微详情返回不同终态,记录 status_mismatch finding,并以最新详情快照作为待确认状态。
  • 回调重试使用同一事件幂等键 upsert 并递增重试计数,不重复写动作历史。补偿拉取同一 run_id + sp_no 只能有一条 item,详情 digest 相同则只更新时间和来源,不重复生成动作。
  • source 优先级用于解释,不用于盲目覆盖:getapprovaldetail 详情快照 > 回调事件 > 手工导入/测试样例。任何跨来源不一致必须留 finding。

请假/补卡 WARCH1 V1 至少应保存:申请类型、申请人、审批人、时间范围或补卡时间、时长、原因摘要、状态、审批历史、来源、外部关联键和同步证据。外出/加班仍需后续样例或处理决策;不可把请假/补卡可读性结论扩展为外出/加班已通过。

同意单击即通过的风险处理不要求回退 OA 主办。WARCH1 已在归档记录中保留动作来源、操作者、时间、状态变化、回调/补偿来源和对账 finding;后续正式历史页和操作规程必须继续突出是否由企微单击同意触发,以及补偿拉取是否与回调一致。

隐私边界:

  • OA DB 可保存完整 sp_no、template_id 和企微 userid,用于补偿、恢复和审计;日志、报告、Issue 和文档只输出脱敏前缀。
  • 不保存原始 XML、密文、Token、EncodingAESKey、access token、Secret 或无治理原始 payload。
  • 表单字段只保存业务必要的规范化字段;如后续确需保存原始 payload,必须另设加密存储、保留期限和访问审计。
  • 普通员工只能看本人历史;审批人看自己处理链路;HR/管理员按范围查看;导出默认脱敏。

9.5 WF8 邮件通道决策

WF8 当前正式验收通道为站内通知和企业微信个人应用消息。邮件通道先记录为冻结项,不作为当前 WF8 硬门禁;三渠道验收在本阶段按“两渠道验收 + 邮件冻结说明”处理。

冻结原因:

  • 当前 R7E 真实试运行尚未完成,邮件是否必要应由真实使用反馈决定。
  • 未确认正式 SMTP 配置、发件域、收件人范围、退信处理和敏感信息脱敏策略前,不应把邮件纳入发布可测结论。
  • 审批邮件容易被转发或进入个人邮箱,消息内容必须比企业微信更严格脱敏。

后续解锁条件:

  • 用户确认邮件是审批通知正式通道,而不是临时辅助提醒。
  • 技术方案写清 SMTP provider、密钥存放、退信处理、失败重试、速率限制和回滚路径。
  • 邮件内容只包含脱敏标题、业务编号、状态和 OA deeplink,不包含完整发票、附件、合同正文、报价、银行卡、身份证或 token。
  • Test_Method 同时覆盖站内、企业微信和邮件;缺 SMTP 或样例收件人时必须标 SKIP,不得写成 PASS。

10. 验收场景

场景 步骤 预期结果
OA 主办审批通过 申请人提交报销、采购或合同事项;审批人在 PC 通过;查看业务详情 单据从草稿到审批中再到已通过;历史、当前状态、通知记录一致
移动端审批 申请人提交单据;审批人从 /mobile/approvals 打开待办并通过 移动端可完成审批;PC 待办同步消失或进入已办
企业微信通知回 OA OA 主办待办产生后发送企业微信提醒;审批人点击 deeplink 打开 OA 对应审批页;审批动作在 OA 完成
企微 HR 审批镜像 员工在企业微信提交请假、补卡、外出或加班;审批人在企业微信处理 OA 通过 wecom_attendance_approval_mirror_v1 同步审批详情、历史、附件和状态
OA 应急 HR 审批 管理员人工开启 oa_hr_emergency_mode_v1 后,员工在 OA 提交 HR/考勤应急单 单据带 EMERGENCY 标记,进入恢复回写队列
企业微信个人应用消息 触发待办后向绑定企业微信成员发送个人应用消息 delivery 为成功且无 invaliduser;手机端可收到消息并点击回到 OA 移动审批
驳回重提 审批人填写原因驳回;申请人查看原因后复制或重建申请 原流程留痕完整;新流程有新的提交记录
退回修改 审批人退回;申请人修改后重提 保留同一业务单号和退回历史;重新进入审批中
撤回 申请人在未完成前撤回 流程终止或回到草稿;审批人待办失效
转审 当前审批人填写原因并转给有权限人员 原审批人待办关闭;目标审批人产生新待办;历史显示转审链路
无审批人阻断 提交时审批规则找不到审批人 提交失败,无半截流程,提示联系管理员
正式主管链路 专用员工提交普通低/中额单据;majianyong 处理待办 待办分配给员工直属主管,审批历史显示 majianyong 处理
公司负责人二审 专用员工提交高额、高风险或例外单据;majianyong 通过后进入 wangshunli 串行节点完整,wangshunli(ceo) 作为老板/总经理节点处理
主管本人申请 majianyong 提交单据 主管本人不能自审,按组织链进入 wangshunli(ceo) 或明确非本人兜底节点
公司负责人本人申请 wangshunli 提交并触发老板/总经理节点 不允许自审;若无非本人兜底审批人,应阻断并提示管理员修正规则
系统管理员无业务审批权 仅 admin 角色账号尝试审批业务单据 服务端拒绝,不因 admin 权限生成审批历史
并发处理 两个窗口同时处理同一任务 只有一个结果生效,另一个提示任务已变化
通知失败不阻断 模拟企业微信通知发送失败 审批提交或处理成功,通知记录进入失败可重试

11. 后续开发拆分建议

后续实现时建议按以下 Issue 拆分,不直接跳到大改代码:

  • A1:审批任务列表与入口收口,覆盖 PC /workflow/tasks、移动 /mobile/approvals 和 Portal 待办摘要。
  • A2:通用状态转换与并发保护,覆盖提交、通过、驳回、退回、撤回、转审。
  • A3:审批权限与当前处理人校验,覆盖越权、自审、停用账号和角色待办。
  • A4:审批历史、审计日志和通知记录一致性。
  • A5:企业微信通知 deeplink 回 OA 验证,覆盖 OA 主办审批回 OA 和企微主办 HR/考勤审批镜像。
  • A6:报销、采购、合同等 OA 主办业务逐个接入统一审批验收;请假、补卡、外出、加班按 wecom_attendance_approval_mirror_v1 单独接入镜像。
  • A7:审批回归脚本与 Playwright PC/移动/企业微信 UA 验证。
  • A8:审批规则配置矩阵落地,覆盖金额阈值、天数阈值、兜底审批人、转审和撤回。
  • A9:权限与数据范围矩阵落地,覆盖附件下载、导出、例外处理和系统管理员最小授权。

R6 首轮试运行只验证已有审批主链路稳定性,不新增复杂审批能力。R6 后续审批效率能力已通过 AP6 v1 落地,当前事实源如下:

  • 待办聚合:PC 和移动统一展示待办、已办、抄送和通知入口。
  • 催办:POST /api/workflow/tasks/:taskId/remind 仅允许申请人、提交人或实际归属人催办本人审批中单据的 pending 任务;同一申请人对同一任务 24 小时内最多 1 次;审批人不能催办自己,admin 单角色不能代催办。
  • 超时提醒:job:workflow-overdue-reminders 只扫描 pending 待办;优先使用 due_date,没有 due_date 时按创建后 24 小时判定;同一任务 24 小时内只发一次超时提醒。
  • 审批效率统计:GET /api/workflow/tasks/summary 聚合待办总数、超时数、最早待处理时间、平均等待小时数,并按业务类型、节点和角色汇总;scope=system 仅 system.audit.view 可读,返回聚合数,不返回申请人明细。
  • 状态与审计:催办和超时提醒不改变审批状态,不替代正式审批动作;通知失败不回滚业务,但必须进入审批历史、审计日志、站内通知或通知投递记录。
  • 后续治理增强:流程配置治理、升级处理、节点 SLA 配置和复杂 BPM 仍需另拆 Issue,不在 AP6 v1 内顺手扩展。

涉及状态机、权限模型、数据库迁移或审批规则调整的 Issue,必须在技术方案中写明回滚策略和回归范围。