feat(工作流):支持本地图编排策略包导入导出 (#195)

* docs: define local workflow package mvp

* docs: fix workflow package api contract

* feat: add local workflow package mvp

* feat(workflow): add package API client

* feat(workflow): add package import interface

* feat(workflow): connect package import flow

* fix(workflow): map package validation errors

* fix(workflow): handle import key generation errors

* feat(workflow): localize package import states

* fix(workflow): reset package import modal on open

---------

Co-authored-by: ruanmingchen <“ruanm@chenchen”>
This commit is contained in:
chenchen
2026-07-14 11:28:37 +08:00
committed by GitHub
parent 2e5c1ff286
commit acfacfe1b3
24 changed files with 3154 additions and 3 deletions
+7
View File
@@ -164,6 +164,10 @@ func permissionForRequest(method, fullPath string) string {
return crudPermission(method, "files")
case strings.HasPrefix(path, "/roles"):
return crudPermission(method, "roles")
case path == "/workflows/:id/package":
return "workflow:read"
case strings.HasPrefix(path, "/workflow-package-inspections"), strings.HasPrefix(path, "/workflow-package-imports"):
return "workflow:write"
case strings.HasPrefix(path, "/workflows"):
if path == "/workflows/validate" || path == "/workflows/dry-run" || strings.HasSuffix(path, "/resume") {
return "workflow:execute"
@@ -257,6 +261,9 @@ func isProcessGlobalMutationPath(path string) bool {
// Workflow runs inherit conversation access; definitions are global.
return !strings.HasPrefix(path, "/workflows/runs/") && path != "/workflows/validate" && path != "/workflows/dry-run"
}
if strings.HasPrefix(path, "/workflow-package-inspections") || strings.HasPrefix(path, "/workflow-package-imports") {
return true
}
if strings.HasPrefix(path, "/knowledge") {
return path != "/knowledge/search"
}
@@ -0,0 +1,20 @@
package security
import (
"net/http"
"testing"
)
func TestWorkflowPackageRoutesHaveExplicitWorkflowPermissions(t *testing.T) {
if got := permissionForRequest(http.MethodGet, "/api/workflows/:id/package"); got != "workflow:read" {
t.Fatalf("export permission=%q", got)
}
for _, path := range []string{"/api/workflow-package-inspections", "/api/workflow-package-inspections/:inspectionId", "/api/workflow-package-imports", "/api/workflow-package-imports/:importId"} {
if got := permissionForRequest(http.MethodGet, path); got != "workflow:write" {
t.Fatalf("%s permission=%q", path, got)
}
}
if !isProcessGlobalMutationPath("/workflow-package-imports") || !isProcessGlobalMutationPath("/workflow-package-inspections") {
t.Fatal("package mutations must require all-resource scope")
}
}