fix(plugins): 插件管理 - 修正官方应用插件的分类与状态显示

AI 审美分析和剪辑工作台在管理页显示为"已停用",原因是三处插件
分类清单不一致:

- 后端 officialApplicationPolicies 缺少 editor-shell
- 管理页 officialApplicationIds 同时缺少 ai-art-critique 和 editor-shell
- 用户插件页另有一份重复清单

后端把这两个插件当作系统协议处理(Kind=protocol),platformAvailable
回退为 false,于是返回"管理员已停用该插件",管理页据此渲染成"已停用"。

修复:

- 后端补上 editor-shell 应用策略(权威修复,决定平台可用性)
- 前端抽取唯一清单 OFFICIAL_APPLICATION_PLUGIN_IDS,管理页与用户插件页
  共用,删除两份重复实现
- 补前后端回归测试,锁定这 8 个官方应用插件

验证:tsc --noEmit 通过;前端 17 项测试通过;后端 TestEditorShell* 与
既有插件测试通过;前后端镜像构建通过。
This commit is contained in:
jay
2026-09-12 21:16:42 +08:00
parent 01a2d171f5
commit 044e220d14
7 changed files with 139 additions and 15 deletions

View File

@@ -76,3 +76,44 @@ func TestArtCritiqueIsUserToggleableApplication(t *testing.T) {
t.Fatalf("AI art critique policy = %#v", policy)
}
}
// Regression: editor-shell was missing from officialApplicationPolicies, so the
// backend classified it as a system protocol and reported it to the admin page
// as "管理员已停用该插件" even though nothing disabled it.
func TestEditorShellIsUserToggleableApplication(t *testing.T) {
policy := pluginManagement(PluginEditorShell, "bundled")
if policy.Origin != PluginOriginOfficial || policy.Kind != PluginKindApplication || policy.ActivationScope != PluginScopeUser || policy.ConfigurationScope != PluginConfigurationNone {
t.Fatalf("editor shell policy = %#v", policy)
}
}
func TestEditorShellReportsPlatformAvailableWithoutPlatformState(t *testing.T) {
db, err := gorm.Open(sqlite.Open("file:"+newID()+"?mode=memory&cache=shared"), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err := db.AutoMigrate(&model.PluginPlatformState{}, &model.UserPluginState{}, &model.AdminAuditEvent{}); err != nil {
t.Fatal(err)
}
center, err := newPluginRuntime(t.TempDir())
if err != nil {
t.Fatal(err)
}
svc := &Service{repo: repository.New(db), pluginRuntime: center}
user := &model.User{ID: "user-1", Role: model.UserRoleUser}
states, err := svc.PluginStatesForUser(user)
if err != nil {
t.Fatal(err)
}
state, ok := states[PluginEditorShell]
if !ok {
t.Fatalf("editor shell missing from plugin states: %#v", states)
}
if !state.PlatformAvailable || !state.CanToggle {
t.Fatalf("editor shell should be a user-toggleable application, got %#v", state)
}
if state.BlockedReason == "管理员已停用该插件" {
t.Fatalf("editor shell reported as admin-disabled: %#v", state)
}
}