Files
hms/wiki/wasm-plugin.md
iven ca50d32f6e
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
feat(health): 添加 erp-health 健康管理模块骨架
新建 erp-health 原生 Rust crate,覆盖设计规格中定义的 5 大业务域:

- 16 个 SeaORM Entity(患者/家属/标签/医生/健康档案/体征/化验单/预约/排班/随访/咨询等)
- 16 表数据库迁移(含索引、外键、默认值、可回滚)
- 40+ API 路由骨架(患者管理/健康数据/预约排班/随访/咨询/医生管理)
- 12 个权限声明(health.patient/health-data/appointment/follow-up/consultation/doctor 各 .list/.manage)
- DTO / Service / Handler / Event 四层架构,Service 使用 todo!() 占位
- erp-server 集成:模块注册 + AppState FromRef 桥接 + 路由挂载

同步更新 CLAUDE.md 项目进度、wiki 知识库、设计规格文档。
2026-04-23 19:59:22 +08:00

126 lines
5.2 KiB
Markdown
Raw Permalink 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.
---
title: WASM 插件系统
updated: 2026-04-23
status: stable
tags: [wasm, plugin, wasmtime, wit]
---
# WASM 插件系统
> 从 [[index]] 导航。关联: [[erp-core]] [[architecture]] [[erp-server]]
## 1. 设计决策
### 为什么选 WASM 而非 Lua / gRPC / dylib
| 方案 | 安全性 | 隔离性 | 性能 | 复杂度 |
|------|--------|--------|------|--------|
| **WASM** | 高(沙箱) | 进程内隔离 | 接近原生 | 中 |
| Lua 脚本 | 中 | 无隔离 | 快 | 低 |
| 进程外 gRPC | 高 | 进程级隔离 | 网络开销 | 高 |
| dylib | 低 | 无隔离 | 原生 | 低 |
核心权衡WASM 在安全和性能间取得最佳平衡。Wasmtime v43 Component Model 提供类型安全的 Host-Plugin 接口Fuel 防止无限循环。
### 架构拓扑
```
┌─────────────────────────────────────────────┐
│ erp-server │
│ ┌───────────┐ ┌────────────────────────┐ │
│ │ EventBus │ │ PluginRuntime(Wasmtime) │ │
│ │(broadcast)│ │ ┌─────┐ ┌─────┐ │ │
│ └─────┬─────┘ │ │CRM │ │库存 │ │ │
│ │ │ └──┬──┘ └──┬──┘ │ │
│ │ │ Host Bridge(自动注入 │ │
│ │ │ tenant_id+权限检查) │ │
│ │ └─────┼──────────────────┘ │
│ ┌─────┴──────┐ │
│ │ DB(SeaORM) │ │
│ └────────────┘ │
└─────────────────────────────────────────────┘
```
### 原型验证 (V1-V6)
全部通过WIT+bindgen 编译、Host 调用插件、插件回调 Host API、async 实例化、Fuel 限制、动态加载。
## 2. 关键文件 + 数据流
### 核心文件
| 文件 | 职责 |
|------|------|
| `crates/erp-plugin-prototype/wit/plugin.wit` | WIT 接口定义Host API + Plugin API |
| `crates/erp-plugin-prototype/src/lib.rs` | Host 运行时Engine/Store/Linker/HostState |
| `crates/erp-plugin-prototype/tests/test_plugin_integration.rs` | V1-V6 集成测试 |
### WIT 接口概要
Host 暴露给插件(`host-api``db_insert` `db_query` `db_update` `db_delete` `event_publish` `config_get` `log_write` `current_user` `check_permission`
插件导出给 Host`plugin-api``init` `on_tenant_created` `handle_event`
### 集成契约
| 方向 | 模块 | 接口 | 触发时机 |
|------|------|------|---------|
| 被调用 ← | [[erp-server]] | `PluginEngine` | 服务启动时恢复插件 |
| 调用 → | [[erp-core]] | `EventBus` | 桥接领域事件到插件 |
| 提供 → | 所有插件 | Host API (9 函数) | 插件运行时 |
## 3. 代码逻辑
### 插件生命周期
```
安装(manifest+WASM) → 注册权限 → 实例化(Wasmtime) → init()
→ 日常: db_query/db_insert 通过 data_handler 自动注入 tenant_id + 权限校验
→ 事件: EventBus → handle_event()
→ 升级: upload 新 WASM → 增量 DDL → 卸载旧实例 → 加载新实例
```
### 权限系统
权限码由 `data_handler.rs``compute_permission_code()` 自动生成:
```
{manifest_id}.{url_entity_name}.{action_suffix}
例: erp-crm.customer.list / erp-crm.customer.manage
```
**权限命名铁律**: `plugin.toml``permissions[].code` 前缀必须与 `schema.entities[].name` 完全一致,每个实体必须声明 `.list` + `.manage`
**Host API 数据约定**: 所有数据参数用 `list<u8>` + JSON 序列化Host 自动注入 id/tenant_id/timestamp
**同步调用**: bindgen 生成的 `call_init`/`call_handle_event` 是同步的,只有实例化可以 async
### 不变量
⚡ Fuel 默认 100 万,耗尽时 WASM trap`wasm trap: interrupt`
`HasSelf<HostState>` 是 Linker 注册的必要类型参数(`Data<'a> = &'a mut HostState`
⚡ Core WASM 必须通过 `wasm-tools component new` 转为 Component 格式才能被 Host 加载
## 4. 活跃问题 + 陷阱
### 历史教训
- CRM 权限码 `tag.manage` vs 实体 `customer_tag` → 三个页面 403迁移 m000038 修复)
- CRM WASM 二进制错误存储了测试插件而非 CRM 插件(重新编译修复)
- 权限未自动分配给 admin 角色 → 403添加 `grant_permissions_to_admin()`
### 注意事项
⚠️ 插件 API 路由用 `Path<(Uuid, String)>` 解析 plugin_id必须用数据库 UUID 而非 manifest_id
⚠️ 修改 WIT 后需重编译 Host crate 和所有插件
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-04-23 | 重构为 5 节结构,插件制作流程移至 `.claude/skills/plugin-development/` |
| 2026-04-19 | CRM 权限码修复 (m000038) |
| 2026-04-18 | 插件权限系统审计 |
> **插件制作完整流程**: 详见 `.claude/skills/plugin-development/SKILL.md`WIT 接口 → 创建 crate → 编译 WASM → 集成测试)