Acquire Codebase Knowledge
github/awesome-copilot
Maps an unfamiliar codebase into seven evidence-backed documents in docs/codebase/, using a scan script and templates, for onboarding or architecture write-ups.
Maps BiSheng's approval-center architecture to exact service files and methods, so a change to approval logic can be located without searching the whole repo.
SKILL.md written in Chinese; this summary is our English description.
$ npx skills add dataelement/bisheng --skill approval-module -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install dataelement/bisheng approval-module --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/approval-module .claude/skills/approval-module && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .claude/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-moduleType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add dataelement/bisheng --skill approval-module -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install dataelement/bisheng approval-module --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/approval-module .agents/skills/approval-module && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .agents/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add dataelement/bisheng --skill approval-module -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install dataelement/bisheng approval-module --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/approval-module .cursor/skills/approval-module && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .cursor/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/dataelement/bisheng.git --path .claude/skills/approval-module--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add dataelement/bisheng --skill approval-module -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install dataelement/bisheng approval-module --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/approval-module .gemini/skills/approval-module && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .gemini/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install dataelement/bisheng approval-moduleInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add dataelement/bisheng --skill approval-module -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/approval-module .github/skills/approval-module && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .github/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add dataelement/bisheng --skill approval-module -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install dataelement/bisheng approval-module --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dataelement/bisheng.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/approval-module .opencode/skills/approval-module && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "approval-module" agent skill from https://github.com/dataelement/bisheng/tree/main/.claude/skills/approval-module into .opencode/skills/approval-module/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "approval-module", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
approval-moduleMaps BiSheng's approval-center architecture to exact service files and methods, so a change to approval logic can be located without searching the whole repo.
Documents a single shared approval engine that every approval scenario in BiSheng reuses: one gateway, one set of routes, and a common flow, node, instance and task model, deliberately separating 'approved' from 'executed' so that passing approval only writes a pending outbox entry, with the actual business action run asynchronously afterward and the instance only marked executed once that action succeeds. A separate, now-deprecated department-file-upload approval system is called out explicitly as compatibility-only, not to be extended and not to be confused with the current engine.
A table of code anchors maps each responsibility to its exact file and key methods: a gateway service handling routing and pass, pending or exception branching; a center service handling task decisions and multi-node advancement; an exception service for retrying, reassigning or skipping a stuck node; and an outbox service that executes and retries the deferred business action. Multi-node flows distinguish OR nodes, where one approval skips the rest of that node and advances, from AND nodes, where every task in the node must approve first, and a node whose handler isn't registered still gets marked approved with an outbox entry rather than left stuck.
The document carries an explicit maintenance contract: any change to the main flow branching, a renamed or added service file, a new preset scenario, a changed database table, an API route, a notification trigger, or a queue routing change must update the matching section of this same reference in the same commit, checked by asking whether any sentence in the doc has become false.
12 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit ed3b461. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
uvFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use uv, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
BiSheng Approval Module Reference loads about 4k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 602 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from dataelement/bisheng at commit ed3b461, republished under its Apache-2.0 licence (© dataelement). 602 words, ~4,004 tokens.
.claude/skills/approval-module/SKILL.md (or your agent's skills folder).本 skill 是审批模块的唯一权威参考,必须与代码永远一致。 当你改动以下任意一项时,同一个改动里必须同步更新本文件对应章节,否则视为改动未完成:
ApprovalGate.request_or_pass 的 pass/flow/exception 分流、decide_task / _advance_after_node_approved 的节点流转)→ 更新 §2 架构与主流程自检:改完代码后问自己"本 skill 里有没有哪句话现在变成假的了?"——有就改它。
审批中心是一套通用多场景审批引擎,所有场景共用同一套网关 / 路由 / 流程 / 节点 / 实例 / 任务 / outbox 机制。
核心原则:审批"通过"与"执行业务"解耦为两步——通过后只写 approval_outbox(PENDING),由 Celery 异步执行业务 on_approved(),成功后实例才置 EXECUTED。
⚠️ 已废弃:另有一套独立的旧系统——部门知识空间文件上传审批(
approval_request表),由approval_service.py+message_handler.py承载,路由在/approval/requests/*与/approval/department-knowledge-space/*。该功能已废弃,仅为兼容存量保留,不要在其上新增功能;新需求一律走审批中心引擎。改审批中心时也不要误改它。
申请人触发业务入口
│
▼
ApprovalGate.request_or_pass() ← 统一网关,所有场景从这里进入
│
路由匹配 (approval_route_rule 表,按 sort_order 自上而下)
│
┌────┴───────────────────────────┐
│ pass 分支 (route_type=pass) │ → instance(APPROVED) + outbox → Celery → on_approved() → EXECUTED
│ flow 分支 (route_type=flow) │ → instance(PENDING) + 首节点 task(PENDING) → 等待审批人
│ 无分支命中 │ → instance(EXCEPTION, route_missing) + 通知管理员
│ 审批人解析为空 │ → instance(EXCEPTION, approver_empty) + 通知管理员
└────────────────────────────────┘
│ (flow 分支被审批人处理)
▼
ApprovalCenterService.decide_task()
│
通过 → _advance_after_node_approved()
├── 有后续节点(node_order 更大) → 解析下一节点审批人 + 建 tasks + 通知审批人;解析为空 → EXCEPTION(approver_empty)
└── 无后续节点(最后节点) → instance(APPROVED) + outbox → Celery → EXECUTED + 通知申请人
拒绝 → instance(REJECTED) + 通知申请人
撤回 → instance(WITHDRAWN) + 通知有 task 的审批人多节点 / 会签:_advance_after_node_approved() 实现顺序流转。
node_mode=or):任一人通过即把同节点其余 PENDING task 置 SKIPPED 并 advance。node_mode=and):同节点全部通过才 advance。handler_key 未注册,记录 error 后仍照常 APPROVED + 建 outbox(避免卡死)。异常实例也留痕:_create_exception_result() 在创建异常后会补写 action='approval.request.submit' 审计日志(与正常 PENDING/PASS 分支一致)。
路径相对
src/backend/bisheng/。这些是定位问题的第一入口。
| 文件 | 职责 | 关键方法 |
|---|---|---|
approval/domain/services/approval_gate.py | 统一入口:路由匹配、实例创建、pass/pending/exception 分流 | request_or_pass()、_create_exception_result()、_notify_admins_of_exception() |
approval/domain/services/approval_center_service.py | 用户端:任务列表/详情、同意/拒绝、撤回、菜单申请、多节点流转 | decide_task()、_advance_after_node_approved()、_dispatch_outbox()、_send_approval_notify() |
approval/domain/services/approval_exception_service.py | 管理端异常处理:重试/指定审批人/跳过节点/取消/标记完成 | assign_approvers()、_resolve_exception_node() |
approval/domain/services/approval_outbox_service.py | outbox 执行与重试;成功后置 instance=EXECUTED | execute_outbox()、retry_outbox() |
approval/domain/services/approval_scenario_admin_service.py | 管理端:场景/分支/流程/节点配置、异常列表 | — |
approval/domain/services/approver_resolver.py | 解析审批人来源 direct_user / department_admin / tenant_admin | resolve_approvers_from_sources() |
approval/domain/services/approval_registry.py | 场景预置目录 + handler 注册表 | with_default_presets()、register_handler()、get_handler() |
approval/domain/services/approval_runtime_handler_factory.py | 为 outbox 执行 / 多节点 advance 重新构造运行时 handler | build_runtime_handler(scenario_code) |
approval/domain/services/approval_notification_service.py | 站内信统一封装 | notify_user() / notify_users() / notify_admins() |
approval/domain/services/user_menu_access_service.py | 菜单授权增删查,含父级菜单依赖自动补全 | grant_menu_access()、revoke_menu_access()、ensure_application_allowed() |
approval/domain/services/approval_service.py + message_handler.py | 旧系统(已废弃):部门知识空间文件上传审批(approval_request 表),与审批中心独立,仅兼容存量、勿新增功能 | ApprovalService.decide_request() |
worker/approval/tasks.py | Celery 任务(走默认 celery 队列) | execute_approval_outbox、retry_approval_outbox |
worker/config.py | Celery 路由配置(审批任务不配路由,fall through 到默认队列) | task_routes |
approval/api/endpoints/approval_user.py | Client 端 API(/api/v1/approval/...) | — |
approval/api/endpoints/approval_admin.py | Platform 管理 API(/api/v1/approval/admin/...) | — |
approval/api/endpoints/approval.py | 旧系统 legacy API(/api/v1/approval/requests/...),已废弃 | — |
| 文件 | 类 |
|---|---|
approval/domain/services/menu_access_handler.py | MenuAccessApprovalHandler |
approval/domain/services/channel_subscribe_scenario_handler.py | ChannelSubscribeScenarioHandler |
approval/domain/services/knowledge_space_subscribe_scenario_handler.py | KnowledgeSpaceSubscribeScenarioHandler |
| 文件 | 职责 |
|---|---|
src/frontend/client/src/components/approval/ApprovalCenterDialog.tsx | 审批中心弹窗(我的审批 + 我的申请 + 时间线) |
src/frontend/client/src/api/approval.ts | 审批 API 封装,含 ApprovalApiError(非 200 自动抛出) |
src/frontend/client/src/pages/MenuUnavailablePage.tsx | 无权限占位页 + 申请入口 |
src/frontend/client/src/layouts/MenuApprovalPluginGate.tsx | 菜单审批路由守卫 |
src/frontend/platform/src/pages/ApprovalPage/index.tsx | 管理后台审批页(场景/分支/流程/节点/异常) |
src/frontend/platform/src/controllers/API/approval.ts | Platform 审批 API 封装 |
三个场景由 ApprovalRegistry.with_default_presets() 注册(仅是"目录/下拉来源",不等于已启用)。每个场景的业务入口在创建 ApprovalGateRequest 时都需要传 applicant_department_id(供 department_admin 审批人来源使用,查 UserDepartmentDao.aget_user_primary_department())。
首次部署自动落库:4.2 频道订阅审批、4.3 知识空间加入审批由 common/init_data.py::_init_default_approval_scenarios()(在 init_default_data 内)为默认租户幂等 seed——各建「默认分支(catch-all, route_type=flow) → 默认流程 → 单节点(node_mode=or 或签)」,审批人来源即资源 owner+manager(频道 channel_owner/channel_manager,知识空间 knowledge_space_owner/knowledge_space_manager),场景 enabled=True。按 tenant_id+scenario_code 判存在即跳过,绝不覆盖人工改动。菜单权限申请(4.1)不自动 seed。新租户不自动 seed,需管理后台手工配置。
menu_access_request)/workspace/menu-unavailable?plugin=xxx → POST /api/v1/approval/menu-access/applyMenuAccessApprovalHandleron_approved 调 UserMenuAccessService.grant_menu_access(),自动补父级依赖(如 knowledge_space → 同时授权 workstation);on_revoke 调 revoke_menu_access()ensure_application_allowed()(menu_approval_mode=false 或已有权限时拒绝)channel_subscribe_request)channel/domain/services/channel_service.py::subscribe_channel()(REVIEW 可见性频道)ChannelSubscribeScenarioHandlerChannelService.sync_direct_channel_user_permissions() 写 ReBAC(OpenFGA) 关系(否则成员不出现在 ReBAC 成员列表)on_approved 先把申请人的 PENDING membership 翻成 ACTIVE 再写 ReBAC(查 membership 注意频道默认只返回 ACTIVE,激活需带非 ACTIVE 状态)_send_channel_approval_notification() 通知审批人knowledge_space_subscribe_request)knowledge/domain/services/knowledge_space_service.py::subscribe_space()(auth_type=APPROVAL)KnowledgeSpaceSubscribeScenarioHandlersync_direct_space_user_permissions() 写 ReBAC 关系_send_space_approval_notification() 通知审批人subscribe_space 对 APPROVAL 空间必须先 await gate.request_or_pass(),按 gate 结果(pass→ACTIVE / pending·exception→PENDING)才通过 _persist_space_member() 写 space_channel_member。严禁在调网关前预写 PENDING membership——否则场景未配置/未启用时网关 raise ApprovalScenarioDisabledError,但 PENDING 行已落库,下次点"关注"会被 subscribe_space 顶部"已 PENDING 直接返回 pending"的早退分支短路,掩盖错误(首次报错、二次假成功)。无场景时每次点击都应一致报错。| 表名 | 说明 | 关键状态字段 |
|---|---|---|
approval_scenario | 租户下启用的审批场景 | enabled |
approval_route_rule | 场景下条件分支(按 sort_order 匹配) | route_type: pass/flow、enabled |
approval_flow_definition | 审批流程定义头 | — |
approval_flow_version | 流程版本快照 | is_active |
approval_node_definition | 流程版本内顺序节点 | node_order、node_mode: or/and、approver_config |
approval_instance | 一次审批申请 | pending/approved/rejected/withdrawn/executed/execute_failed/exception/cancelled |
approval_task | 分配给审批人的节点待办 | pending/approved/rejected/skipped/cancelled |
approval_exception | 异常记录 | open/resolved,exception_type: route_missing/approver_empty/execute_failed |
approval_outbox | 业务执行队列 | pending/success/failed |
approval_action_log | 时间线日志 | — |
user_menu_access | 用户级菜单授权(菜单审批专用) | active/revoked |
approval_request | 旧系统(已废弃):部门知识空间文件上传审批,仅兼容存量 | — |
模型定义见
approval/domain/models/approval_instance.py、approval_scenario.py、user_menu_access.py。approval_instance.latest_approver_user_id字段已定义但当前从未赋值(已知限制,需要时在decide_task里补)。
业务执行走 outbox:通过后写 approval_outbox(PENDING) → Celery execute_approval_outbox 执行 handler.on_approved() → 成功 outbox=SUCCESS、instance=EXECUTED;失败 outbox=FAILED、instance=EXECUTE_FAILED 并建 execute_failed 异常。
原则:业务回调(
on_approved等)不得静默失败。 该执行成功/失败由「是否抛异常」判定:抛异常 → outbox=FAILED +execute_failed异常暴露问题;正常返回 → 一律视为成功并置 instance=EXECUTED。因此前置条件缺失(如找不到要激活的 membership/资源)必须 raise,绝不能return {'status':'xxx'}之类把失败伪装成成功——否则会出现 instance=executed 但业务实际没生效的「假成功」,且无任何告警。
dispatch 入口(两处,功能相同名字不同):
approval_center_service.py::_dispatch_outbox(outbox_id) — decide_task 最后节点通过 / skip_nodeapproval_gate.py PASS 分支 — 调 execute_approval_outbox.delay(outbox_id)Celery 队列:走默认 celery 队列。 worker/config.py 不为 bisheng.worker.approval.* 配路由,任务自然 fall through 到默认队列。workflow_celery 专供工作流 DAG 执行,审批任务不占用。
⚠️ 部署时必须有 worker 消费默认
celery队列(run_celery.py的all/file模式都含),否则审批通过后业务不执行。站内信发送是同步写库,不依赖 Celery。
启动消费默认队列的 worker:
uv run celery -A bisheng.worker.main worker -l info -c 100 -P threads -n default@%h全局前缀
/api/v1。以代码为准(approval_user.py/approval_admin.py/approval.py)。
/approval)GET /approval/my-tasks # 我的待办(审批人视角)
GET /approval/my-tasks/{task_id} # 任务详情
POST /approval/tasks/{task_id}/decision # 同意/拒绝
GET /approval/my-requests # 我的申请(申请人视角)
GET /approval/instances/{instance_id} # 实例详情(tasks + flow_nodes + action_logs)
POST /approval/instances/{instance_id}/withdraw # 撤回
GET /approval/menu-access/pending-check # 菜单申请前置校验
POST /approval/menu-access/apply # 菜单权限申请
POST /approval/menu-access/{instance_id}/revoke-grant # 撤销菜单授权(审批人)/approval/admin)GET /approval/admin/scenario-presets # 预置场景目录(下拉来源)
GET /approval/admin/scenarios # 场景列表
POST /approval/admin/scenarios # 新增场景
PUT /approval/admin/scenarios/{scenario_id} # 更新场景
DELETE /approval/admin/scenarios/{scenario_id} # 删除场景
GET /approval/admin/scenarios/{scenario_id}/routes # 分支列表
POST /approval/admin/scenarios/{scenario_id}/routes # 新增分支
PUT /approval/admin/routes/{route_rule_id} # 更新分支
DELETE /approval/admin/routes/{route_rule_id} # 删除分支
PATCH /approval/admin/scenarios/{scenario_id}/routes/reorder # 分支排序
GET /approval/admin/scenarios/{scenario_id}/flows # 流程列表
POST /approval/admin/scenarios/{scenario_id}/flows # 新增流程
PUT /approval/admin/flows/{flow_definition_id} # 更新流程
DELETE /approval/admin/flows/{flow_definition_id} # 删除流程
GET /approval/admin/flows/{flow_definition_id}/nodes # 节点配置
PUT /approval/admin/flows/{flow_definition_id}/nodes # 提交节点(全量提交触发新版本)
GET /approval/admin/flows/{flow_definition_id}/versions/{flow_version_id} # 版本预览
GET /approval/admin/exceptions # 异常列表
POST /approval/admin/exceptions/{exception_id}/retry # 重试/指定审批人/跳过节点/标记完成
POST /approval/admin/exceptions/{exception_id}/cancel # 取消审批(必须填原因)/approval/requests、/approval/department-knowledge-space)— ⚠️ 已废弃部门知识空间文件上传审批,独立于审批中心,见 approval.py。已废弃,仅兼容存量数据,不要在此新增/扩展接口。
| 触发时机 | 接收人 | 实现位置 |
|---|---|---|
| 创建审批任务(菜单申请) | 审批人 | ApprovalCenterService._send_menu_access_approval_messages() |
| 频道审批创建(PENDING) | 审批人 | ChannelService._send_channel_approval_notification() |
| 知识空间审批创建(PENDING) | 审批人 | KnowledgeSpaceService._send_space_approval_notification() |
| 中间节点通过、生成下一节点任务 | 下一节点审批人 | _advance_after_node_approved() → _send_approval_notify('approval_task_pending') |
| 审批通过(最后节点 finalize) | 申请人 | _advance_after_node_approved() → _send_approval_notify('approval_instance_approved') |
| 审批拒绝 | 申请人 | decide_task() reject 分支 |
| 申请撤回 | 有 task 的审批人 | ApprovalCenterService.withdraw_instance() |
| 异常产生(route_missing/approver_empty) | 管理员(AdminRole) | ApprovalGate._notify_admins_of_exception() / ApprovalNotificationService.notify_admins() |
| 异常取消 | 申请人 | ApprovalExceptionService.cancel_exception_api() |
注:申请人侧"通过"通知是在最后节点 finalize 时发的(即审批通过即通知),不等 outbox 业务真正执行完。若要"业务执行成功"的精确通知,需在
execute_outbox成功回调里补。
get_instance_detail 返回三组数据,前端合并展示:
action_logs[action=submitted] ← 提交申请
flow_nodes (按 node_order 排序) ← 完整流程骨架(来自 approval_node_definition,含未到达节点)
├── 已有 task → 实际状态
└── 无 task → 灰色"未到达"
action_logs[action!=submitted] ← 撤回/取消等其他日志flow_nodes 解决了"tasks 只有已创建节点"的问题,能展示完整流程定义。
条件分支 match_config 格式:
{} // 无条件,始终命中(catch-all)
{"field": "applicant_role", "value": "dept_admin"} // 申请人是部门管理员
{"field": "menu_key", "value": "knowledge_space"} // 申请特定菜单
{"field": "space_type", "value": "department"} // 知识空间类型applicant_role 枚举:admin(系统管理员) / tenant_admin(租户管理员) / dept_admin(部门管理员) / regular_user(普通用户, catch-all) / role_{id}(特定角色)。
节点 approver_config.sources 格式:
[
{"type": "direct_user", "user_ids": [701], "user_names": ["00017"]},
{"type": "department_admin"},
{"type": "tenant_admin"}
]user_names 由前端保存时写入,用于节点卡片直接显示用户名,避免二次查库。
SELECT id, status, applicant_user_id FROM approval_instance WHERE id=<N>;
SELECT id, status, error_summary FROM approval_outbox WHERE instance_id=<N>;_dispatch_outbox 没调pending → 没有 worker 消费默认 celery 队列failed → 看 error_summary,并查 approval_exception 的 execute_failed手动补偿:
# set_current_tenant_id(tenant_id)
# handler = await build_runtime_handler(outbox.handler_key)
# await handler.on_approved(instance_id, outbox.payload_snapshot)SELECT id, approver_user_id, status FROM approval_task WHERE instance_id=<N>;
SELECT id, exception_type, status, detail FROM approval_exception WHERE instance_id=<N>;若异常类型是 approver_empty:检查 approval_instance.applicant_department_id 是否为 NULL,以及节点 approver_config.sources 里 department_admin 是否依赖部门。
检查对应 sync_direct_channel_user_permissions / sync_direct_space_user_permissions 是否在该激活路径被调用(写 ReBAC/OpenFGA 关系)。若 instance=executed 但 space_channel_member.status 仍为 PENDING,说明 on_approved 没真正激活成员(见 §6 的"业务回调不得静默失败"原则)。
审批相关测试在 src/backend/test/approval/(asyncio_mode=auto)。新测试放到该目录,不放 test/ 根。
cd src/backend && uv run pytest test/approval/© dataelement, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/approval-module of dataelement/bisheng.
Open the folder on GitHubat commit ed3b461
BiSheng Approval Module Reference next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| BiSheng Approval Module Reference this skilldataelement/bisheng | 12k | — | ~4k | Automated safety check: Pass | Apache-2.0 | |
| Acquire Codebase Knowledgegithub/awesome-copilot | 40k | 1 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Repomix Codebase Exploreryamadashy/repomix | 29k | 1 repos | ~2.7k | Automated safety check: Pass | MIT | |
| Code Graph Mermaid Diagramstrailofbits/skills | 7.4k | 1 repos | ~1.7k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| tilth Code Reading CLIjahala/tilth | 352 | — | ~1.1k | Automated safety check: Pass | MIT | |
| BTCA Local Repo Searchstickerdaniel/linkedin-mcp-server | 3.8k | — | ~660 | Automated safety check: Pass | Apache-2.0 |
github/awesome-copilot
Maps an unfamiliar codebase into seven evidence-backed documents in docs/codebase/, using a scan script and templates, for onboarding or architecture write-ups.
yamadashy/repomix
Packs a local or remote repository into a single AI-friendly file with the Repomix CLI, then reads and searches that output to explain structure, find patterns or report metrics.
trailofbits/skills
Generates Mermaid diagrams from Trailmark code graphs, including call graphs, class hierarchies, module dependency maps, complexity heatmaps and attack surface data flows.
jahala/tilth
Replaces grep, cat, find and ls with the tilth CLI, which returns AST-aware outlines, definitions, usages and callers across many languages in one call.
stickerdaniel/linkedin-mcp-server
Searches git repositories cloned locally under a sandbox folder to answer questions with cited links and complete code snippets.
nikolai-vysotskyi/trace-mcp
Routes code exploration through trace-mcp's indexed dependency graph, using symbol search, outlines, call graphs and change-impact tools instead of Read, Grep and Glob.
dataelement/bisheng
Builds or edits Word .docx documents inside BiSheng's code executor with python-docx, handling Chinese fonts, tables of contents, page numbers and official-document layout.
dataelement/bisheng
Builds PowerPoint decks in BiSheng's code executor with python-pptx, from scratch, from a supplied template or by rewriting an existing file, with Chinese layout rules.
dataelement/bisheng
Builds, edits and cleans Excel workbooks inside BiSheng's code executor using openpyxl, with LibreOffice recalculation and a pre-delivery check.
dataelement/bisheng
Reviews BiSheng spec, design and tasks documents with checklists for PRD gaps, handover readiness and acceptance traceability, producing a report or an LGTM.
dataelement/bisheng
Runs a light convention check on one finished spec-driven task, choosing checks by task type and ending in pass, pass-with-notes or needs-fix.
dataelement/bisheng
Runs a seven-dimension code review on a finished feature, comparing the diff against a base branch and the feature's spec, design and task files.
Works with
Categories
Maps BiSheng's approval-center architecture to exact service files and methods, so a change to approval logic can be located without searching the whole repo. Documents a single shared approval engine that every approval scenario in BiSheng reuses: one gateway, one set of routes, and a common flow, node, instance and task model, deliberately separating 'approved' from 'executed' so that passing approval only writes a pending outbox entry, with the actual business action run asynchronously afterward and the instance only marked executed once that action succeeds. A separate, now-deprecated department-file-upload approval system is called out explicitly as compatibility-only, not to be extended and not to be confused with the current engine.
BiSheng Approval Module Reference fits situations like: fixing a bug where an approved request's business action never ran; adding a new preset approval scenario to BiSheng's approval center; locating which service handles multi-node approval advancement; updating this reference after changing the approval module's code.
Run `npx skills add dataelement/bisheng --skill approval-module -a claude-code`. Or copy the skill folder (.claude/skills/approval-module in dataelement/bisheng) into .claude/skills/approval-module in your project. Claude Code loads it when a task matches its description.
Run `npx skills add dataelement/bisheng --skill approval-module -a codex`. Or copy the skill folder (.claude/skills/approval-module in dataelement/bisheng) into .agents/skills/approval-module in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dataelement/bisheng --skill approval-module -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/approval-module, .gemini/skills/approval-module, .github/skills/approval-module and .opencode/skills/approval-module in your project.
Going by SKILL.md and its folder, BiSheng Approval Module Reference needs the command-line tools its instructions call (uv).
SKILL.md contains no URLs. Its commands use uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
BiSheng Approval Module Reference is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with BiSheng Approval Module Reference: Acquire Codebase Knowledge (github/awesome-copilot, 40k stars), Repomix Codebase Explorer (yamadashy/repomix, 29k stars), Code Graph Mermaid Diagrams (trailofbits/skills, 7.4k stars) and tilth Code Reading CLI (jahala/tilth, 352 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
dataelement (a GitHub organization) maintains it in dataelement/bisheng, which has 12,028 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 8, 2026.
Source: dataelement/bisheng on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.