Files
erp/docs/superpowers/specs/2026-04-18-plugin-system-enhancement-design.md
iven 841766b168
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
fix(用户管理): 修复用户列表页面加载失败问题
修复用户列表页面加载失败导致测试超时的问题,确保页面元素正确渲染
2026-04-19 08:46:28 +08:00

6.2 KiB
Raw Blame History

插件系统增强设计规格

Context

插件系统是 ERP 平台的核心差异化能力当前声明式层面manifest schema、动态表、前端页面已达 90% 成熟度。但 WASM 逻辑层存在根本性限制:

  1. 插件无法自主查询数据db_query 的 filter/pagination 参数被忽略,只能使用预填充结果
  2. 无读后写一致性 — 延迟刷新模型导致插件在一次调用中无法读取自己刚写入的数据
  3. 聚合只有 COUNT — 缺少 SUM/AVG/MAX/MIN无法支撑财务、统计类场景
  4. 热更新无原子回滚 — 旧版本先卸载再加载新版本,中间失败无保障
  5. Schema 变更只支持新增实体 — 不支持已有实体的字段演进

这些限制使插件系统只能支撑"数据管理+展示"型轻量场景CRM、简单进销存无法支撑需要复杂业务逻辑的行业财务、制造、电商

本次增强的目标:让插件逻辑层从 40% 提升到 80%+,使系统能真正承载不同行业的定制化需求。


改动 1混合执行模型解决查询和读后写一致性

问题

host.rs:99-109db_query 忽略 _filter_pagination 参数,只从 query_results 预填充缓存取数据。插件无法自主构造查询。

方案:读操作走实时 SQL + 写操作保持延迟批量 + 读前自动 flush

核心流程变更:

当前:
  WASM 调用 db_insert() → 入队 pending_ops
  WASM 调用 db_query()  → 从预填充缓存读(忽略 filter/pagination
  WASM 结束             → flush 全部 pending_ops

改为:
  WASM 调用 db_insert() → 入队 pending_ops
  WASM 调用 db_query()  → 先 flush pending_ops → 执行真实 SQL 查询 → 返回结果
  WASM 结束             → flush 剩余 pending_ops

改动文件

1. crates/erp-plugin/src/host.rs

HostState 新增字段:

pub struct HostState {
    // ... 现有字段保留 ...
    pub(crate) db: Option<DatabaseConnection>,
    pub(crate) event_bus: Option<EventBus>,
}

db_query 实现变更 — 使用 tokio::runtime::Handle::current()spawn_blocking 内执行异步 DB 操作:

  1. block_on(flush_ops(...)) 清空 pending writes
  2. 解析 filter/pagination 参数
  3. 调用 DynamicTableManager::build_query_sql() 构建查询
  4. block_on 执行查询并返回结果

向后兼容:db = None 时走旧的预填充路径。

2. crates/erp-plugin/src/dynamic_table.rs

新增 build_query_sql 方法,复用 data_service.rs 中的查询构建逻辑。

向后兼容

  • HostState::new() 不传 db → 走旧的预填充路径
  • execute_wasm() 传 db → 走新的实时查询路径
  • 现有 WASM 插件无需修改

改动 2扩展聚合查询

问题

data_service.rs:655aggregate 方法只支持 GROUP BY + COUNT(*)

方案

新增 aggregate_multi 方法支持 SUM/AVG/MAX/MIN。

改动文件:

  1. data_service.rs — 新增 AggregateDefAggregateFuncAggregateResult 类型和 aggregate_multi 方法
  2. dynamic_table.rs — 新增 build_aggregate_multi_sql 方法
  3. data_handler.rs — 扩展聚合 API 端点
  4. 前端 Dashboard Widget 适配多聚合返回格式

SQL 示例:

SELECT _f_status as key,
       COUNT(*) as count,
       COALESCE(SUM(_f_amount), 0) as sum_amount,
       COALESCE(AVG(_f_price), 0) as avg_price
FROM plugin_erp_crm__order
WHERE tenant_id = $1 AND deleted_at IS NULL
GROUP BY _f_status

改动 3热更新原子回滚

问题

service.rs:578-585 — 先 unload(old)load(new),中间失败无回滚。

方案:先加载新版本到临时 key成功后原子替换

改动文件:

  1. service.rs — upgrade 方法改用临时 key 加载新版本
  2. engine.rs — 新增 rename_plugin 方法

安全保证:新版本加载失败 → 旧版本仍在运行,零停机。


改动 4Schema 演进ALTER TABLE 支持)

问题

升级时只处理新增实体CREATE TABLE不处理已有实体的字段变更。

方案:利用 JSONB 特性实现轻量级 Schema 演进

大部分字段变更不需要 DDLJSONB 天然支持),仅新增 filterable/sortable 字段需 ALTER TABLE ADD Generated Column + 索引。

改动文件:

  1. service.rs — upgrade 方法增加 schema diff 逻辑
  2. dynamic_table.rs — 新增 FieldDiffdiff_entity_fieldsalter_add_generated_columns

实施顺序

阶段 改动 复杂度 影响范围
1 热更新原子回滚 engine.rs + service.rs
2 Schema 演进ALTER TABLE 中低 service.rs + dynamic_table.rs
3 扩展聚合查询 data_service.rs + data_handler.rs + dynamic_table.rs
4 混合执行模型(查询能力) host.rs + engine.rs + dynamic_table.rs

验证方案

阶段 1热更新回滚

  1. 上传损坏的 WASM 二进制 → 验证旧版本仍在运行
  2. 上传正确的新版本 → 验证成功切换

阶段 2Schema 演进

  1. 升级插件增加 filterable 字段 → 验证 ALTER TABLE 正确执行
  2. 旧数据上新 Generated Column 值正确填充

阶段 3聚合查询

  1. 创建测试数据,调用聚合 API → 验证 SUM/AVG 结果正确
  2. 前端 Dashboard 展示正确

阶段 4混合执行模型

  1. 插件 WASM 中 db_insert 后立即 db_query → 读后写一致性
  2. 带 filter 的 db_query → 过滤结果正确
  3. 旧插件(预填充模式)仍能正常工作
  4. 多次连续 db_query 不超过 Fuel 限制

关键文件清单

文件 改动类型
crates/erp-plugin/src/host.rs 重构 db_query + 新增 db/事件总线字段
crates/erp-plugin/src/engine.rs 调整 execute_wasm + 新增 rename_plugin
crates/erp-plugin/src/service.rs 升级流程回滚安全 + schema diff
crates/erp-plugin/src/dynamic_table.rs 新增 build_query_sql + alter_add_generated_columns + diff_entity_fields
crates/erp-plugin/src/data_service.rs 新增 aggregate_multi + AggregateDef
crates/erp-plugin/src/data_handler.rs 扩展聚合 API
apps/web/src/pages/PluginDashboardPage.tsx 适配多聚合返回格式