DEVELOPER GUIDE / PROTOCOL V1

独立业务模块开发指南

本指南、接口清单、界面和 SDK 均内嵌于 platform.exe。平台统一管理模块进程;模块通过双向 RPC 使用平台的身份、持久化记录和审计能力。

支持 Windows 与 Linux amd64、多账号登录、组织用户与角色权限、模块模拟测试和管理员发布。平台采用 JSON 文件存储,业务模块为受信任的独立进程。公网部署通过 HTTPS 反向代理,底座只监听回环地址;仅安装经过审查的模块。Linux 模块入口使用无扩展名的 ELF 文件,Windows 使用 EXE,安装包必须与服务器架构一致。

Windows 服务运行指南:安装、自启、日志与故障恢复 →

1. 架构与职责

浏览器 → 平台 HTTP → go-plugin → 业务模块 Execute
业务模块 → go-plugin MuxBroker → 平台 Host.Call
                                   ├── identity.get
                                   ├── records.list
                                   └── records.create + 原子审计

平台提供持久化和公共能力;模块提供 Describe 页面描述、Execute 业务校验。浏览器身份不能覆盖平台身份。模块 ID 由连接绑定,数据按模块隔离。首版串行执行模块动作,每次 RPC 等待上限 10 秒,超时不代表写入未发生。调用失败后模块会被停止,可从管理页面重新启动。

2. 接口文档

入口用途
GET /healthz无会话健康检查
GET /api/bootstrap取得当前会话、登录状态、权限和 CSRF token
GET /api/modules发现安装包、运行状态、字段描述与授权
POST /api/modules/register注册并执行受信任模块
POST /api/modules/{id}/start启动已注册模块
POST /api/modules/{id}/stop停止模块;下次平台启动仍自动加载已注册模块
POST /api/modules/{id}/unregister取消注册,保留数据;重启后不自动加载
POST /api/actions/{id}/create调用模块登记动作
POST /api/actions/{id}/list调用模块列表动作
GET /api/audit最近 100 条审计

先 GET / 建立 HttpOnly、SameSite=Strict 本机会话 cookie,再 GET /api/bootstrap。写接口使用 application/json,携带 X-CSRF-Token。浏览器跨来源请求被拒绝。首次使用先调用 POST /api/auth/setup(name、password)初始化管理员;之后调用 POST /api/auth/login(username、password)登录。使用返回的新 csrf_token 与更新后的 cookie。密码至少12个字符。未登录返回401,无操作权限返回403。

POST /api/actions/workorder/create
X-CSRF-Token: 从 bootstrap 取得的 token
{
  "request_id": "至少16字符、最多128字符的唯一请求号",
  "payload": {"title":"维修打印机","reporter":"张三","priority":"普通","description":"无法打印"}
}

成功:{"data":{"id":"…","created_at":"…","created_by":"local-admin","values":{…}}}
失败:{"code":"INVALID_ARGUMENT","error":"标题不能为空"}

HTTP 状态:400 校验错误;401 无会话;403 无权限或 CSRF 错误;409 幂等冲突;503 模块不可用。同一次登记重试使用原 request_id 和相同内容;同一键改变内容返回冲突。

3. 模块反向调用平台

服务 / 能力名请求与结果
identity.get返回 id、name、mode。
records.listcollection 为合法标识,返回 Record 数组,按登记时间倒序。
records.createcollection + JSON 对象 payload,返回 Record;登记与审计一起持久化,并按请求号去重。
reply, err := host.Call(modulekit.HostRequest{
    Service: "records.create", Collection: "tickets",
    Payload: normalizedJSON,
    RequestID: request.RequestID, ActorID: request.ActorID,
})
if err != nil { return modulekit.Response{}, err }
return modulekit.Response{Data:reply.Data, Code:reply.Code, Error:reply.Error}, nil

必须传递当前 Execute 请求的 RequestID、ActorID;平台服务端核对委托上下文及能力。不要在 Execute 返回后异步调用 host,也不要缓存用户上下文。记录 ID、创建时间、创建者由平台生成,业务模块不得伪造。collection 按连接绑定的模块自动分区。

模块界面必须遵守 adminui-v1

所有业务模块统一使用 adminui 的浅色侧栏、紫色强调色、卡片、表单与表格,兼容深浅主题。协议 v1 通过 Describe 和 record_columns 由底座生成界面,不接受自定义前端资源。开发前必须阅读 界面样板 与 完整规范;SDK 包含相同规范及离线样板。

4. 从本网站创建一个模块

  1. 阅读 完整纯文本协议 和 机器接口清单。下载并解压 SDK 到模块源码目录,得到 platform-sdk/。
  2. 新建 go.mod,引用下面的模块路径。SDK 已包含双向 RPC 适配,不需复制平台内部代码。
  3. 实现 Business.Describe() 和 Business.Execute(request, host),在 main 中调用 modulekit.Serve。
  4. 模块执行服务端必填、类型、枚举、长度校验;默认值和业务状态在模块设置。表单描述仅帮助界面展示。
  5. 执行 go mod tidy,再 go build -trimpath -o workorder.exe .。首次构建需要 Go 和依赖下载网络;运行编译后的 EXE 不需要 Go。
module example.local/workorder
go 1.24.0
require collab.local/platform v0.0.0
replace collab.local/platform => ./platform-sdk
type Business interface {
    Describe() modulekit.Descriptor
    Execute(modulekit.Request, modulekit.Host) (modulekit.Response, error)
}
func main() { modulekit.Serve(&Workorder{}) }

Describe 必须返回 ID、Name、Version、Protocol、Description、Fields。协议号为 1。字段支持 text、textarea、select;字段名为小写英文字母开头,后续允许小写字母、数字、下划线或短横线,总长不超过 40。支持 Required、Options、MaxLength。首版仅标准表单和列表,新增标准模块不用修改平台 UI。

5. 模块打包与注册

platform.exe
modules/
  workorder/
    manifest.json
    workorder.exe
data/                  首次运行自动创建,不能用升级包覆盖
{
  "id":"workorder", "name":"工单登记", "version":"0.1.0",
  "protocol":1, "entry":"workorder.exe",
  "capabilities":["identity.get","records.list","records.create"]
}

manifest 的 ID、Version、Protocol 必须与二进制 Describe 一致;entry 必须是该模块目录中的 EXE 文件名。只将可信包放入模块目录,在平台首页刷新、检查能力并点击注册。也可以调用:

POST /api/modules/register
{"id":"workorder","capabilities":["identity.get","records.list","records.create"]}

注册通过后立即启动、加载菜单和表单,将批准记录保存到 data/registry.json。平台下次启动时自动加载。安装包被发现不等于被执行,必须经过本机管理员批准。禁止在模块运行时覆盖 EXE;先停止、备份、替换包,再启动。首版没有自动迁移、自动回退或热升级能力。

6. AI 开发与验收流程

给 AI 的任务应包含本网站地址、业务字段、校验规则、模块 ID 和安装路径。要求 AI 先读取指南及下载 SDK,在独立源码目录生成程序,然后编译并注册。保留读取响应、SDK 校验和、构建结果及测试记录;不能仅声称“遵守文档”。

请读取 http://127.0.0.1:17880/docs/module-guide.txt 和 /docs/api.json,下载 /devkit.zip。
仅使用网站 SDK,实现 workorder 模块:标题、登记人、优先级、问题描述。
实现 create/list 动作,调用平台身份与记录服务,不自行保存数据。
验证必填、长度、优先级枚举,状态由后端设为“已登记”。
编译 EXE,制作 manifest,注册到平台,测试重启后数据和模块恢复。

后台管理与权限

侧栏提供组织架构、用户管理、角色与权限、操作审计。支持部门层级、新增及编辑用户、分配角色、重置密码和停用账号。角色权限控制模块查看/管理、各模块业务查看/登记、组织管理、用户管理、角色管理和审计查看,服务端与反向RPC共同校验。多角色权限取并集;账号停用、密码重置和角色调整对已有会话生效。

GET /api/admin 返回后台数据及 revision;POST /api/admin/departments、/users、/roles 提交 revision 和对应对象。版本冲突返回409。初始管理员及内置系统管理员角色受保护。部门暂不隔离模块内的业务数据。旧版跨模块权限仍覆盖全部模块(含以后注册的模块),精确授权时请仅选择对应模块权限。完整请求见机器接口清单。

按模块注册权限和角色模板(v0.3)

在 manifest.json 中声明 permissions(id、name、action)和可选 role_templates(id、name、description、permissions)。基础权限为 模块ID.read 对应 list、模块ID.create 对应 create;可选工作流权限见下节;模板角色ID须以“模块ID-”开头,并且仅可包含本模块权限。成功注册时平台收录权限目录并创建缺失的模板角色,不自动给用户分配。重新注册会保留管理员对角色的修改。

在“角色与权限”新增或编辑角色,按模块分组勾选,再到“用户管理”分配。一个角色可跨模块组合,一个用户可有多个角色,权限取并集。旧模块省略权限声明时会自动生成查看/登记权限。取消注册保留角色授权与权限目录,目录标为未注册。业务接口和反向RPC同时限制模块权限,模块级账号只能发现获准使用的模块。

可选 record_columns 用于展示后端计算字段,如请假模块的 duration_days。完整示例见纯文本指南与机器接口清单。请假登记按自然日计算半天,不包含审批、工作日历或假期余额扣减。

模块自提交、模拟与批准发布(v0.4)

后台“模块发布审核”可签发限定模块ID和有效期的提交令牌。开发者将 manifest.json、EXE、simulation.json 打成根目录ZIP,以 application/zip、Authorization: Bearer 提交令牌、X-Submission-Request-ID 调用 POST /api/module-submissions。不需要管理员账号或浏览器会话。提交只产生待审候选包,不执行EXE,不改变正式模块和用户权限。

管理员先审阅清单、权限、能力及SHA256,点击“运行模拟测试”。测试在独立临时数据目录执行,覆盖必填与未知字段校验、有效登记、幂等冲突、只读账号拦截、审计、持久化恢复。测试通过后再明确批准平台能力并点击“批准正式发布”。模拟会执行EXE,只隔离平台数据,不是操作系统安全沙箱或恶意程序检测。

simulation.json须包含非空 valid_payload 和有效且内容不同的 conflict_payload。ZIP压缩及解压后均不得超过64MiB,路径、链接和多余文件被拒绝。模拟报告绑定包指纹,包变化必须重新提交测试。发布先备份旧包,失败尝试回退,不覆盖正式业务数据。任务中断在平台启动时核对或标记为失败。详细端点见纯文本指南和机器接口清单。

通用工作流动作(v0.6)

底座现支持 edit、submit、publish、reject 四种可选动作。Descriptor.actions 声明名称、按钮文字、字段、适用状态与本人限制,manifest.permissions 必须声明对应模块限定权限。底座负责通用界面、当前账号权限检查、记录持久化和审计;业务模块负责状态转换、所有权、版本冲突及重试幂等。旧的 business.create 不包含这些新动作。CMS 示例提供编辑与总编两个角色模板,注册不自动分配给用户。完整契约见纯文本指南第15节。

用户自助 API Key 与 Agent 接入

注册用户登录后点击右上角 API Key,自助生成带有效期的个人密钥并交给 Agent。无需逐模块申请提交令牌。密钥继承账号实时权限,支持进一步限权、到期和撤销,完整 Key 只显示一次,服务器保存哈希。使用 Authorization: Bearer 调用 API,不需要 Cookie 或 CSRF;Key 的生成和撤销需要浏览器登录。普通用户可提交应用候选包并查看自己的提交,拥有 modules.manage 权限的 Key 可调用模拟测试和批准正式发布接口。Agent 工具 scripts/agent_publish_module.py 支持完整发布流程。详情见纯文本指南开头与机器接口清单。

7. 存储与安全边界

data/state.json 包含业务记录、幂等结果及审计,临时文件写入、同步后替换。仅支持单个平台进程使用同一数据目录,启动时会获取目录锁;存储会整体重写,适合演示和小数据验证。迁移到生产前应增加数据库、分页、限流、企业身份认证与数据范围控制、资源隔离和备份恢复方案。停止平台后备份整个 data/ 目录;不应直接编辑正在使用的数据文件。

平台使用 go-plugin 的 net/rpc 后端验证简化方案,不使用 Go 原生动态库 plugin。握手不是安全认证,能力限制也不能阻止恶意 EXE 访问操作系统。代码依赖及接口版本应固定;平台升级后按协议进行兼容验证。

HashiCorp go-plugin 官方资料 · Go net/rpc 文档