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

184 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 插件系统增强设计规格
## 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-109``db_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 新增字段:
```rust
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:655``aggregate` 方法只支持 `GROUP BY + COUNT(*)`
### 方案
新增 `aggregate_multi` 方法支持 SUM/AVG/MAX/MIN。
改动文件:
1. `data_service.rs` — 新增 `AggregateDef``AggregateFunc``AggregateResult` 类型和 `aggregate_multi` 方法
2. `dynamic_table.rs` — 新增 `build_aggregate_multi_sql` 方法
3. `data_handler.rs` — 扩展聚合 API 端点
4. 前端 Dashboard Widget 适配多聚合返回格式
SQL 示例:
```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` — 新增 `FieldDiff``diff_entity_fields``alter_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` | 适配多聚合返回格式 |