Files
sub2api-add/docs/BUSINESS_PLUGIN_V1_IMPLEMENTATION.md
Qiufeng 028b505c36
Business Plugins CI / check (plugin-admin) (push) Successful in 1m35s
Business Plugins CI / check (subscription-admin) (push) Successful in 1m29s
feat: add controlled plugin marketplace lifecycle
2026-08-28 00:51:34 +08:00

3.4 KiB
Raw Permalink Blame History

Business Plugin V1 实现边界与验收

状态:控制面入口已实现;业务插件按包独立接入

1. 唯一入口

plugins/plugin-admin 是通用 Business Plugin V1 控制面。它的首页和默认菜单只能表达“插件管理”,不表达任何具体业务域,也不默认打开订阅、支付或其他业务页面。

控制面负责:

  • 展示插件市场、已入库、运行中和可升级的插件包;
  • 校验清单、签名、文件哈希和 Core 兼容性;
  • 下载/上传入库、启用、停用、升级、回滚、删除和配置;
  • 显示运行状态、健康检查结果和操作审计;
  • 对插件声明的管理员菜单执行预览和应用。

控制面不负责:

  • 订阅商品、余额、订单、支付、配额或请求计费;
  • 任何业务插件自己的页面和领域数据;
  • Core 数据库、Core 用户表或 .s2plugin transport ABI。

2. 安装后注入流程

管理员登录 plugin-admin
        |
        v
插件市场/本地上传 -> 选择业务插件包
        |
        v
清单 + 签名 + 哈希 + Core 兼容性校验
        |
        v
下载并校验后写入独立 revision,初始为 disabled(已入库、待启用)
        |
        v
启用 -> 启动独立服务端口 -> healthz/readyz/版本检查
        |
        v
菜单预览 -> 管理员确认 -> 应用 custom_menu_items
        |
        v
Core 管理员菜单出现该插件自己的入口

每个插件使用自己的 plugin_id、版本、端口、服务进程、UI 和菜单 ID。停用或卸载插件时,只移除该插件自己声明的菜单项,不触碰其他插件或 Core 数据。

3. 订阅插件的位置

plugins/subscription-admin 是第一个业务插件样例,而不是控制面。它只有在管理员通过 plugin-admin 安装、启用并应用菜单后才出现。卸载订阅插件只删除插件资源和自身投影,不删除 Core 的套餐、订阅、余额、订单、用量或审计。

订阅插件的 V1 只读取 Core 现有管理员 API;余额购买、续费、撤销和退款写操作必须等待版本化 Core 原子接口,不得把多个 Admin API 拼成一次购买。

4. 登录与安全边界

  • 控制面和业务插件均复用 Core 管理员登录及 2FA,不创建插件用户表;普通 Core 用户统一拒绝。
  • 浏览器只持有插件自己的 HttpOnly 会话和 CSRF token;Core access/refresh token、Admin Key 只存在插件服务端。
  • 插件后端通过精确 allowlist 调用 Core API,不提供任意 URL 代理,不连接 Core PostgreSQL/Redis。
  • 插件包必须签名;未签名包仅限开发环境 loopback 测试。

5. 功能验收最小条件

  1. 打开 plugin-admin 首屏看到插件目录,而不是订阅页面。
  2. 未安装订阅包时,目录可以为空,左侧不会出现订阅菜单。
  3. 安装并启用一个包后,详情页显示该包的状态、版本和健康结果。
  4. 菜单预览只新增该包自己的菜单项;应用后 Core 管理员菜单才出现该入口。
  5. 停用或卸载后入口消失,其他菜单保持不变。
  6. 425px、900px、1440px 三种视口均无横向溢出、遮挡或凭据泄漏。

6. 后续插件模板

新增业务插件只需提供独立清单、服务、UI、Core API allowlist 和菜单声明,并遵守本文件的安装生命周期。插件管理控制面不因新增业务域而增加订阅、支付或其他领域分支。