# 小核心与公共能力扩展(v0.20) 工作流、待办、站内通知与附件已经作为独立提供者实现。普通用户先看[简明使用指南](/docs/collaboration),开发者看[完整接入接口](/docs/collaboration-extensions.md)。 ## 先理解三个层次 | 层级 | 放哪些功能 | 职责 | |---|---|---| | 核心底座 | 身份认证、权限执行、统一网关、扩展注册与路由、运行隔离、基础审计 | 确保请求身份可信、能力调用受控、模块生命周期可靠。保持小而稳定。 | | 公共能力扩展 | 工作流、待办、通知、附件、搜索、定时任务、报表、外部连接器 | 提供可被多个业务应用复用的服务。按能力契约申请、授权和调用。 | | 业务应用 | 请假、报销、合同、资产、采购、CMS | 定义自有 H5、业务 API、业务规则和业务数据,使用公共扩展完成协作。 | **模块与层次的关系:** 模块是交付和运行的单元;公共能力扩展和业务应用都可以做成模块。两者区别在职责及授权:公共扩展需要管理员明确批准为服务提供者,普通业务应用只能申请并调用已批准能力。 **谁负责业务正确性:** 核心检查真实用户、动作权限和能力授权;工作流扩展负责流程实例、节点及审批任务;报销等应用负责金额、额度、单据状态和自己的数据库事务。扩展不能绕过核心授权,也不代替业务规则。 **三层如何协作:** 接入工作流后的目标路径是:报销 H5 → 核心网关 → 报销应用 → 核心能力路由 → 工作流扩展。人工审批等待时保存状态并返回,不占用持续 RPC;跨模块状态同步还需可靠事件/outbox方案。 **概念与当前实现:** v0.20 已提供工作流、统一待办、站内通知和附件四个独立公共扩展,各有自定义 H5、Docker 容器及 PostgreSQL 账号/schema;工作流基础版支持顺序审批。定时任务保持可选内置扩展;records、通讯录、数据库和云连接器暂为宿主兼容适配器。搜索、报表、通用事件总线等仍待接入。 **部署方式与层次不同:** 公共扩展可以是独立 Docker 进程,也可以是独立代码包的内置扩展。当前采用兼容方式逐步迁出,不能把“可扩展”理解为“所有能力均已独立进程化”。 核心负责可信身份、动作和能力授权、受控路由、模块生命周期及运行隔离。工作流、待办、通知、附件、搜索等通过扩展契约接入,业务应用保留自己的 H5、业务规则和数据。语言选择由运行配置决定,核心不依赖某个工作流引擎。 ## 本次实际边界 | 类型 | 已实现的交付方式 | 当前例子 | |---|---|---| | 核心契约 | 能力命名、接口主版本、依赖检查和身份绑定 | identity.get 与受控路由 | | 独立公共能力提供者 | 管理员批准的模块,通过现有 RPC/Docker 运行 | workflow、todos、notifications、attachments;text-tools 为契约示例 | | 可选内置扩展 | 独立 Go 包,通过端口接口接入 | scheduler 调度引擎,可关闭 | | 兼容适配器 | 旧能力经统一分发,保持原权限和数据格式 | records、directory、database、cloud | | 业务应用 | 申请能力并声明依赖版本 | extension-demo、现有 CMS 等 | 兼容适配器目前仍在宿主进程。调度引擎已移至独立包,但其认证 HTTP 适配层、页面和权限兼容入口保留在宿主,默认仍编译并启用。没有宣称所有功能都已成为独立安装服务;v0.20 增加独立的 workflow、todos、notifications、attachments;没有安装 Warm-Flow/Flowable 或通用事件总线,顺序审批为自研基础实现。 ## 提供能力 公共扩展仍是协议1/2模块,具备 H5 管理入口、动作权限和原有隔离约束。额外声明: ```json { "id": "workflow", "extension": { "api_version": 1, "provides": [ {"name": "workflow.start", "action": "create"}, {"name": "workflow.read", "action": "list"} ] } } ``` 这是契约片段,完整包仍需入口、名称、版本、协议、H5、能力和权限。导出能力必须属于本模块命名空间,不能覆盖 identity/records/database/directory/cloud 等保留能力。导出动作必须声明权限;非 list/create 的动作还必须出现在 Describe 中。 提供者程序由运维安装到受控模块目录,管理员核对代码、接口版本、资源和数据迁移后,通过模块注册界面明确勾选“批准为公共能力扩展提供者”,或调用已有注册接口传 extension_approved=true。该决定持久化在注册表,不由包自行授予。个人候选包发布拒绝创建或覆盖公共扩展,即使调用者是管理员也不绕过此流程。 后续提供者升级仍由运维处理:先检查已登记依赖及未完成业务实例,在维护窗口解除依赖注册、备份、替换并重新注册。当前没有运行中流程迁移、自动升级编排或引擎内部实例统计接口;不能把“无注册依赖”当成“无未完成流程”。 ## 使用能力 ```json { "capabilities": ["identity.get", "records.list", "records.create", "workflow.start"], "dependencies": [{"extension": "workflow", "api_version": 1}] } ``` 消费者后端继续通过 host.call 调用 Service=workflow.start,传 JSON Payload、当前 ActorID 和 RequestID。不能传任意网络地址或借用管理员身份。新能力要求提供者已登记、明确获批、正在运行,且接口主版本完全一致;包版本与接口主版本是不同概念。 调用路径:业务 H5 → 核心网关 → 业务模块 Execute → 反向 host.call → 核心扩展路由 → 提供者 Execute → 原路径返回。 核心检查消费者能力批准、消费者当前动作权限、提供者动作权限,以及原始委托 Key 权限上限。读动作不得调用写扩展。接收者获得底座写入的 extension 元数据:capability、caller_module、caller_action、caller_request_id;Payload 内同名字段没有可信含义。底座会生成按“调用模块+能力+用户+原请求号”隔离的确定性扩展请求号,并绑定当前提供者实例。重试保持原号,但提供者仍须自己实现持久幂等。 同一个业务请求对同一能力的多次调用共享扩展请求号,适合一次逻辑操作;不要用同一号发起多个不同写入。提供者如需多个子操作,应以明确业务操作ID建立自己的子事务/幂等规则。 扩展仍受全局/账号额度、排队及10秒调用预算约束,同模块仍串行。嵌套调用继承剩余截止时间,不获得新的无限预算;静态依赖图和运行调用链检查循环,链深最多8,实际还受账号并发额度限制。超时可能已有写入,核心不自动重试业务。 ## 生命周期与模拟隔离 启动按依赖拓扑排序。缺失、停用、崩溃或不兼容的依赖会在业务执行前返回 DEPENDENCY_UNAVAILABLE,不借机启动提供者或降级绕过授权。无关应用不经过该依赖检查。 有已登记依赖的提供者不能直接 stop/restart/unregister,暂停的消费者也计入依赖,需先按维护方案解除其注册。程序意外退出属于故障恢复,由原有监督机制处理。非法循环注册配置在启动前拒绝。 应用发布模拟复制已批准依赖的程序和声明资源到独立空间,最多16个依赖提供者、总程序资源256MiB。使用新的模拟账号、records及数据库scope,不转发到生产提供者,也不复制生产业务数据、Key或数据库凭据。依赖未就绪则模拟失败。个人发布申请扩展能力时,还需账号已获对应提供者动作权限。 ## 定时任务的迁出 调度、Cron解析、错过处理、并发额度、日志与重启恢复位于独立 scheduler 包。通过 Authorize、Execute、Persist、NewID、Trace 端口接入宿主,不导入平台服务实现。旧 scheduled-jobs.json、接口和任务权限保持兼容,不迁移或删除任务数据。 运维设置 OA_SCHEDULER_ENABLED=false 可不启动调度器;默认启用,非法值拒绝启动。关闭时任务接口返回503,历史文件保留;当前侧栏兼容入口仍显示。再次启用后按既有错过策略处理,不无条件补跑历史任务。 ## 查看和开发 模块管理的“公共能力扩展”查看提供者、兼容适配器、可选内置扩展、接口版本、状态及依赖应用。模块详情“能力与权限”展示本包导出和依赖。GET /api/extensions 仅向 modules.manage 开放,既有 Docker 管理仍负责独立进程扩展的资源与生命周期。 参考实现为文本工具扩展及消费者示例;它仅验证架构,不是工作流引擎。可分别构建 extension-text-tools 和 extension-demo 命令,Linux入口名为 text-tools、extension-demo;Windows使用.exe后缀并同步修改清单。先注册提供者,再注册消费者,给普通用户同时授予消费者动作和text-tools.read。不要使用生产业务数据验收。 四个协同扩展的实例、任务、事件、通知已读及附件分片存于各自PG空间。所有参与人使用核心用户ID,单次接口快速持久化后返回,不占用RPC等待人工审批。待办按流程状态查询、通知按事务事件读取;这不是通用消息总线,也不提供跨库原子事务。详细限制和调用示例见[协同扩展指南](/docs/collaboration-extensions.md)。