Files
erp/crates/erp-server/migration/src/m20260419_000039_entity_registry_columns.rs
iven ef89ed38a1
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(plugin): P1 跨插件数据引用系统 — 后端 Phase 1-3
实现跨插件实体引用的基础后端能力:

Phase 1 — Manifest 扩展 + Entity Registry 数据层:
- PluginField 新增 ref_plugin/ref_fallback_label 支持跨插件引用声明
- PluginRelation 新增 name/relation_type/display_field(CRM 已在用的字段)
- PluginEntity 新增 is_public 标记可被其他插件引用的实体
- 数据库迁移:plugin_entities 新增 manifest_id + is_public 列 + 索引
- SeaORM Entity 和 install 流程同步更新

Phase 2 — 后端跨插件引用解析 + 校验:
- data_service: 新增 resolve_cross_plugin_entity/is_plugin_active 函数
- validate_ref_entities: 支持 ref_plugin 字段,目标插件未安装时跳过校验(软警告)
- host.rs: HostState 新增 cross_plugin_entities 映射,db_query 支持点分记号
- engine.rs: execute_wasm 自动构建跨插件实体映射

Phase 3 — API 端点:
- POST /plugins/{id}/{entity}/resolve-labels 批量标签解析
- GET /plugin-registry/entities 公开实体注册表查询
2026-04-19 00:49:00 +08:00

52 lines
1.5 KiB
Rust
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.

use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// plugin_entities 新增 manifest_id 列 — 避免跨插件查询时 JOIN plugins 表
manager
.get_connection()
.execute_unprepared(
r#"
ALTER TABLE plugin_entities
ADD COLUMN IF NOT EXISTS manifest_id TEXT NOT NULL DEFAULT '';
ALTER TABLE plugin_entities
ADD COLUMN IF NOT EXISTS is_public BOOLEAN NOT NULL DEFAULT false;
-- 回填 manifest_id从 plugins.manifest_json 提取 metadata.id
UPDATE plugin_entities pe
SET manifest_id = COALESCE(p.manifest_json->'metadata'->>'id', '')
FROM plugins p
WHERE pe.plugin_id = p.id AND pe.deleted_at IS NULL;
-- 跨插件实体查找索引
CREATE INDEX IF NOT EXISTS idx_plugin_entities_cross_ref
ON plugin_entities (manifest_id, entity_name, tenant_id)
WHERE deleted_at IS NULL;
"#,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_unprepared(
r#"
DROP INDEX IF EXISTS idx_plugin_entities_cross_ref;
ALTER TABLE plugin_entities DROP COLUMN IF EXISTS is_public;
ALTER TABLE plugin_entities DROP COLUMN IF EXISTS manifest_id;
"#,
)
.await?;
Ok(())
}
}