Skip to content

Nexo — 2026-09-27 迭代需求文档 ​

范围:落地审批平台首期。总 PRD 见 lamolabs-docs#54(审批平台总 PRD),本文承接其 §6.1 MVP 范围,只裁剪不扩张;产品语义(槽位语法、三种发起方式、会签/或签判定、三层状态机等)一律以总 PRD 为准,本文不复述其推导,只登记本期落地口径与降级决策。 验收标准见第 8 节,本文档定义"做什么"与"为什么";"怎么做"以同目录技术方案(design.md)为准。

1. 背景与目标 ​

2026-09-20 迭代交付权限平台首期时,明确挂了一条账:"审批平台仍是长期 PRD、未立项,本期写操作直落真实表,只预留审批门控开关位"(见 0920 PRD §4.1)。本期即是那条挂账所指的"审批平台上线迭代"。

同时,生态内所有审批仍停留在 IM 人工喊话(总 PRD P1-P5):无统一入口、无结构化记录、规则靠口头约定、无 SLA、每个场景都得重做一遍表单和流转。

本期新建 nexo-approval-api(审批平台后端,端口 3003、单库 nexo_approval) 与 nexo-approval-console(统一审批门户前端),一次落地引擎内核 + 人可用的门户两条线:模板配置、三种发起方式、两阶段槽位解析、条件分支、三种判定策略、审批操作与三层状态机、append-only 审计,以及动态表单渲染、审批详情页、待办与我发起的列表。

核心目标(对应总 PRD P1/P2/P3/P5):

  1. 有引擎:审批规则从口头约定变成模板 JSON,改人不改代码(P3);
  2. 有入口:发起方与审批方在一个门户里看完整条审批单,不再翻 IM(P1);
  3. 可追溯:每一次操作落 ApprovalAction + AuditLog,仅追加不可改(P2);
  4. 可复用:三种发起方式走同一条装配管线,新场景接入不新增引擎代码(P5)。

P4(SLA / 超时自动裁决)本期不做 —— 超时引擎与 IM 通知一并放到下期,理由见 §4.2。

2. 承接与已知欠账 ​

欠账项处理排期
0920 PRD §11 候补第一优先:nexo-account / nexo-im-api 接入 SDK 鉴权,偿还"合法 JWT 即放行"本期纳入为并行还债线。审批平台是第三个 perm-api 消费者,三家一次接完能在同一批用例里验证 SDK 契约,分两期反而要回归两遍2026-09-27
0920 PRD §4.1:perm-api 硬删除等高危写操作预留了审批门控开关位,未接本期只交付审批平台本体,perm-api 侧的实际接入(含回调签名、epoch 快照校验)不在本期,避免双平台同期互踩——与 0913→0920 的处理方式一致下期
nexo-auth#60 服务与仓库更名 nexo-account 未完成本期不动存量仓库;新服务的配置与文档一律按 nexo-account 最终命名书写,不再产生新的 nexo-auth 引用挂账
生态无审计平台沿用 0920 的投递适配层模式:审批平台本地落 AuditLog 表 + 结构化日志,投递目标可替换沿用

3. 功能需求 ​

FR 与任务映射见 §7;每条 FR 的完整产品语义见总 PRD 对应章节,此处只登记本期落地边界。

FR-1 审批模板管理(总 PRD §4.1) 系统必须支持创建、编辑、查询审批模板,模板持有 form_schema / flow_config / timeout_config / defaults 四份 JSON 配置。

FR-2 模板配置强校验 系统必须在模板写入前校验四份 JSON 的结构合法性:字段类型枚举、节点 ID 唯一、next 指向存在的节点、无环、 命名合法、countersign_rule 与 strategy 自洽。校验不过即拒绝写入,不存半成品模板。

FR-3 资源类型注册与模板绑定(总 PRD §4.2 方式一) 系统必须支持注册 resource_type 并绑定到一个审批模板,type_key 全局唯一,记录注册方 owner。

FR-4 三种发起方式同构装配(总 PRD §4.2) 系统必须支持 resource_type / template_id / template_config 三种入参创建审批单,三者仅在"取模板"这一步分叉,取到模板后走完全相同的装配管线;内联模板不持久化为可复用模板,仅绑定当前审批单。

FR-5 第一阶段槽位预填(总 PRD §4.3 步骤 1) 系统必须在创建审批单时,用 payload 中的值预填 fill_by: "system" 的表单字段,返回审批单 ID 与详情页 URL,审批单状态置 pending,此时不实例化节点。

FR-6 第二阶段槽位解析与校验(总 PRD §4.3 步骤 3) 系统必须在提交人提交时合并 payload + submitter 数据,替换模板中全部 (缺失时回落 defaults),并在替换后校验:必填槽位无缺失、审批人槽位解析结果非空且为合法用户。校验失败返回错误并停留在填写态,不产生半实例化的审批单。

FR-7 条件分支求值与节点实例化(总 PRD §4.1 / 数据模型 flow_config) 系统必须按 next.if 顺序求值结构化条件(slot / operator / value,支持 == != > >= < <= in not_in),确定最终节点序列,实例化 ApprovalNode 列表,审批单状态置 in_progress。dynamic_nodes 仅在被条件路由命中时实例化。

FR-8 角色审批人解析(总 PRD §5.6) 系统必须将 type: "role" 的审批人解析为具体用户列表,解析结果快照存入节点的 approvers,不在审批过程中二次查询;解析依赖 nexo-perm-api 新增的角色成员反查接口。

FR-9 判定引擎(总 PRD §4.3) 系统必须实现三种节点策略:single(一人决出)、any(任一通过即通过,全员拒绝才拒绝,其余人置 cancelled)、countersign(all / majority / ratio 三种 mode + veto_users 一票否决)。

FR-10 审批操作与三层状态机(总 PRD §4.3) 系统必须支持通过 / 拒绝 / 撤回 / 评论四种操作,并维护审批单、节点、审批人三层状态的一致流转;通过、拒绝、撤回各落一条 ApprovalAction,评论只落 ApprovalComment。

FR-11 业务方取消(本期新增,见 §4.6) 系统必须提供业务方身份可调的取消接口,用于业务单据作废时同步终止审批单,终态为 cancelled,与发起方主动 withdrawn 区分。

FR-12 审计日志(总 PRD §4.6 / §5.3) 系统必须对模板创建、模板编辑、资源类型注册、资源类型改绑、发起、提交、通过、拒绝、撤回、取消十个动作落 AuditLog(动作码见技术方案 §7.2),表仅追加,库层拒绝更新与删除。

FR-13 查询接口(总 PRD §4.3 步骤 6 / §4.4) 系统必须提供:按 ID 查审批单状态(业务方用)、审批单详情(含节点与时间线)、我的待审批列表、我发起的列表,后两者支持分页与状态筛选。

FR-14 平台自身接口鉴权(总 PRD §5.3) 系统必须在 nexo-perm-api 注册自身权限点并接入 /internal/check 判定,管理接口按平台管理员/业务方管理员角色管控,不得出现任何硬编码管理员逻辑。

FR-15 动态表单渲染器(总 PRD §4.1) 门户必须根据 form_schema 渲染表单,支持文本、数字、日期、下拉、多选、是/否六种字段类型,并按 fill_by(system / submitter / approver)× 当前用户角色决定每个字段的只读或可写。

FR-16 审批详情页(总 PRD §4.3 / §4.4) 门户必须提供单一详情页承载全流程:预填数据展示、提交人补充填写并提交、审批人操作、流转时间线、resource_url 跳转业务上下文。平台不单独提供"发起表单"页。

FR-17 待办与我发起的(总 PRD §4.4) 门户必须提供"我的待审批"与"我发起的"两个列表,聚合所有业务方的审批单,支持分页与状态筛选。

FR-18 桌面壳挂载 桌面壳侧边栏必须挂载审批门户入口,登录态与子应用切换沿用 nexo-perm-console / nexo-user-console 既有方案。

FR-19 存量服务接入 SDK 鉴权(承接 §2 第一条) nexo-account 与 nexo-im-api 的管理接口必须改为经 nexo-backend-sdk 鉴权客户端判定,移除"合法 JWT 即放行"。

4. 本期裁剪与降级决策 ​

以下六条是总 PRD §7.2「待决策(开放问题)」为空、但实际卡在关键路径上的口子。本期就地收口,收口结论同步回填总 PRD #54。

4.1 附件字段移出 MVP ​

总 PRD §4.1 把"附件上传"列进 MVP 字段类型,但全生态没有对象存储:nexo-im-api 的消息类型只有 'text',全仓检索无任何 OSS/S3/MinIO/upload 实现。照搬会让本期顺带做一个文件服务。本期表单字段类型收敛为文本 / 数字 / 日期 / 下拉 / 多选 / 是否六种;附件与富文本、动态表格、关联资源选择器一并列入候补(§11)。业务上下文靠 resource_url 跳转承接。

4.2 通知与超时引擎不进本期 ​

总 PRD §4.5 的 IM 通知与多级超时依赖两个不存在的东西:nexo-im-api 没有系统/机器人消息推送的 internal 接口(现有 /conversations/{id}/messages 是用户态,机器人发不出去),超时 escalate 需要汇报线而 nexo-perm-api 只有组织与角色、查不出上级。本期门户待办即通知:审批人靠"我的待审批"列表与未处理计数感知,不推送、不自动裁决。下期同时交付 im-api 系统推送接口与超时扫描器。

随之降级:审批单状态机本期不出现 auto_approved / auto_rejected 两个终态(枚举位保留,无代码路径产生)。

4.3 escalate 语义重定义 ​

即便下期做超时,"升级通知上级"也无数据来源。口径改为:模板通过 槽位显式声明升级对象,平台不推导上下级关系。本期只在模板 schema 校验里认这个槽位,不实现动作。

4.4 删除 multi_level 策略枚举 ​

flow_config 的节点串联本身就是"多级",节点上再挂一个 multi_level 策略是同一语义的第二套实现,会让判定引擎出现两条互相覆盖的路径。本期 strategy 枚举收敛为 single / countersign / any 三种,多级审批 = 多个串联节点。

4.5 或签判定规则补死 ​

总 PRD §4.3 的或签状态机只写了"有人拒绝但其他人未处理 → in_progress",没写终态条件。本期定死:任一人通过 → 节点 approved,其余人置 cancelled;全员拒绝 → 节点 rejected。单人拒绝不终止或签节点。

4.6 两处数据模型缺口一次建全 ​

  • 业务方取消:总 PRD 只给了发起方"撤回",业务单据作废(如发布单关闭)时审批单会成孤儿。本期补 cancelled 终态与业务方取消接口(FR-11)。
  • 数据隔离字段:总 PRD §5.3 要求"审批单按业务方隔离",但 ApprovalOrder 没有归属字段,方式二/三完全无归属。本期建表即加 namespace(对齐 nexo-perm-api 命名空间口径)。隔离字段本期建全,按隔离过滤的列表行为放到下期——避免为了补字段做二次迁移。

5. 明确不做(Out of Scope) ​

  • IM 通知推送与站内通知中心(§4.2)
  • 超时引擎:计时器、多级阈值、remind / escalate / auto_approve / auto_reject(§4.2)
  • 附件上传与富文本、动态表格、关联资源选择器(§4.1)
  • 转交 / 加签(总 PRD §6.2)
  • Webhook 回调(总 PRD §6.2,本期业务方走按 ID 轮询)
  • 模板可视化编排界面(本期模板经 API 与 JSON 编辑器维护,见 §10 Q2)
  • 资源类型管理界面(本期经 API 注册)
  • 按业务方隔离的列表过滤行为(§4.6,字段本期建,行为下期)
  • nexo-perm-api 高危写操作接入审批门控(§2)
  • 审批统计看板、业务方申请模板创建权限(总 PRD §6.2)
  • i18n(总 PRD §5.5,本期仅中文)

6. 非功能需求 ​

  • 性能:审批单创建 API < 1s;审批操作 < 1s;详情页首屏 < 2s;待办列表首屏 < 2s 且分页(总 PRD §5.1)
  • 安全:ApprovalAction / AuditLog append-only,无更新与删除路径;平台自身接口全部经 perm-api 判定,零硬编码管理员(FR-14)
  • 解耦:审批平台不落地用户与角色数据,角色成员解析结果仅作为节点快照存储(总 PRD §5.6)
  • 幂等:同一审批人对同一节点重复提交同一操作必须幂等,不产生第二条 ApprovalAction
  • 可用性:平台故障不得反向阻塞业务方创建流程之外的既有功能——本期无存量接入方,回滚 = 停服务 + 壳隐藏入口

7. 任务映射 ​

24 个任务已建 issue 并挂组织 Project,锚点 nexo-2026-09-27:Bxx/Fxx/Txx;总追踪见 lamolabs-docs#86。 分工:前端(F 线)全部 @wshiqyuan,其余(B / T 线)全部 @snailuu。

编号IssueFR
B01nexo-approval-api#1 服务骨架与核心数据模型全部地基
B02nexo-approval-api#2 模板管理接口与配置强校验器FR-1 / FR-2
B03nexo-approval-api#3 资源类型注册与模板绑定FR-3
B04nexo-approval-api#4 三路发起同构装配与第一阶段预填FR-4 / FR-5
B05nexo-approval-api#5 第二阶段槽位解析与提交校验FR-6
B06nexo-approval-api#6 条件分支求值与节点实例化FR-7
B07nexo-approval-api#7 角色审批人解析与节点快照FR-8
B08nexo-approval-api#8 判定引擎三策略FR-9
B09nexo-approval-api#9 审批操作与三层状态机FR-10
B10nexo-approval-api#10 业务方取消与 cancelled 终态FR-11
B11nexo-approval-api#11 append-only 审计日志FR-12
B12nexo-approval-api#12 查询、待办与我发起的列表FR-13
B13nexo-approval-api#13 平台自身接口鉴权与权限点注册FR-14
B14nexo-perm-api#35 角色成员反查 internal 接口FR-8
B15nexo-auth#83 账号中心接入 SDK 鉴权FR-19
B16nexo-im-api#85 IM 管理侧接入 SDK 鉴权FR-19
F01nexo-approval-console#1 门户骨架与登录态前端地基
F02nexo-approval-console#2 动态表单渲染器与读写矩阵FR-15
F03nexo-approval-console#3 审批详情页FR-16
F04nexo-approval-console#4 我的待审批与未处理计数FR-17
F05nexo-approval-console#5 我发起的与进度查看FR-17
F06nexo-approval-console#6 模板 JSON 编辑器与校验预览FR-1 / §10 Q2
F07nexo-app#63 壳侧边栏挂载审批门户入口FR-18
T01lamolabs-docs#87 验收用例编写与预跑归档全部

8. 验收标准 ​

  • 验收用例见同目录 tc.md(由 T01 维护并预跑归档证据,门禁逐条映射见该 issue 的「门禁映射」表),覆盖:
    • 三种发起方式产出结构一致的审批单(同一模板分别走 resource_type / template_id / template_config,装配结果逐字段比对一致)
    • 总 PRD 数据模型里的 tpl_release_prod 模板,is_urgent 取 true / false 两条分支各跑通一次,节点序列符合预期
    • 会签三种 mode(all / majority / ratio)各一条,外加 veto_users 一票否决立即拒绝一条
    • 或签两条终态:任一通过 → 其余 cancelled;全员拒绝 → 节点 rejected(§4.5)
    • 槽位校验失败路径:必填槽位缺失、审批人解析为空,均停留在填写态且不产生节点
    • 撤回与业务方取消两条终态区分正确
    • 审计完整性:一单走完后 ApprovalAction 与 AuditLog 条数与操作数一致,且无更新/删除接口可用
    • 门户主流程:一个人从收到链接到审批完成全程不碰 API
  • 硬阈值实测取数不得估算:审批单创建、审批操作两个 API 的 p99 响应时间

9. 排期与发布(概要) ​

  • 开发窗口 09-22 至 09-26,09-27 验收会;前后端并行策略沿用 0920 做法——接口契约在技术方案冻结后,F 线按契约 mock 先行,不等 B 线
  • 发布顺序:test 环境全量联调(09-26)→ 验收通过后 prod 发布 + 首个模板种子;回滚 = 停服务 + 壳隐藏入口,对现有业务零影响(本期无存量业务方接入)
  • 逐日排期见技术方案 design.md §15;验收底线为 B01–B09 + B12(门禁 #1–#5、#7),B10 / B11 / B13 / B15 / B16 允许顺延至验收会前一晚

10. 待评审收口 ​

编号事项倾向口径
Q1首批接入场景。总 PRD §2.3 写的是"发布审批(发布平台)",但发布平台无仓库、总 PRD #50 仍是 p2 草稿——照此排期,"新场景接入无需开发"(P5)没有真实消费者可验证改用权限授予审批作为首批场景:nexo-perm-console 现状是"有管理员角色即可直接授权、无二次确认",把 POST /api/subject-roles 与 /api/direct-grants 改为先落审批单,消费者现成且有真实风险敞口。发布平台作为第二个场景接入,反而能真正验证 P5。本期只验证引擎与门户,场景接入落在下期
Q2模板维护方式本期 API + JSON 编辑器 + 实时 schema 校验 + 节点序列预览;可视化编排留候补。理由:flow_config 结构本期还会随实现微调,先做可视化会返工
Q3审批平台权限点粒度沿用 0920 Q2 口径,按资源粒度建点(模板 / 资源类型 / 审批单 / 审计),不按端点逐一建
Q4会签 ratio 的 threshold 边界≥ threshold 判通过(总 PRD 数据模型已写"通过比例 ≥ threshold"),本期不做可配置的取整策略
Q5template_config 内联模板是否走 FR-2 全量校验走。内联路径与持久化模板共用同一校验器,校验不过直接拒绝创建
Q6技术方案对总 PRD 数据模型的四处偏离(三路统一 template_snapshot、审批人拆独立表、节点序列物化为线性 seq、append-only 由 DB 触发器兜底)全部采纳。API 对外形状与总 PRD 一致,偏离全在存储层;逐条理由见 design.md §7.1 与 §18。评审通过后回填总 PRD #54 数据模型章节

11. 候补(登记,本期不做) ​

  • IM 系统消息推送 internal 接口 + 审批通知适配层(下期第一优先)
  • 超时扫描器与多级超时动作、auto_approved / auto_rejected 终态落地
  • 首批业务场景接入(Q1 收口后落地)与按业务方隔离的列表过滤
  • 附件上传(依赖对象存储或最小文件服务立项)、富文本、动态表格、关联资源选择器
  • 转交 / 加签、Webhook 回调、审批统计看板
  • 模板可视化编排、资源类型管理界面
  • nexo-perm-api 高危写操作接入审批门控(偿还 0920 §4.1 预留开关位)

12. 风险与降级 ​

风险应对
首批消费者缺位:发布平台未立项,P5"接入无需开发"本期无法端到端证明本期验收只证明引擎与门户;P5 的证明推到场景接入迭代。Q1 建议改用权限授予审批,把消费者从"等发布平台"变成"现成的 perm-console"
双新仓并行(后端 + 前端),接口契约漂移沿用 0920 做法:技术方案接口契约章节为冻结源,变更须先改文档再改代码
动态表单渲染器是前端单点大件(6 种类型 × 3 种 fill_by × 3 种角色视角)F 线优先级最高,骨架与渲染器在开发窗口前两天完成;矩阵用例进 tc.md 逐格验收
三路发起方式容易长成三套代码装配管线定为单一入口,三路仅"取模板"一步分叉;验收用例强制三路结果逐字段比对(§8 第一条)
角色成员反查是跨仓依赖,perm-api 侧排期若滑,FR-8 阻塞该接口是 perm-api 单文件读接口,排在 B 线最前;滑期降级为审批人只支持 type: "user",角色审批人顺延
本期同时还 0920 的接入债(FR-19),两件事抢窗口FR-19 是两个中间件替换,排在验收会前一晚亦可;不得反向挤占 B 线引擎任务

13. 名词解释 ​

口径与总 PRD #54 完全一致(审批模板 / 资源类型 / 审批单 / 审批节点 / 槽位 / 会签 / 或签 / 一票否决 / 条件分支 / 内联模板等),本文不重复登记;本期特有的收口与降级见 §4。