Files
Agent-System/internal/workflowdef/bootstrap.go
T
weichenandCursor f07178fa73 feat(service): enforce three-workflow governance and instance lifecycle
Wire catalog policy, v2 manifests, stage access, activation metadata fixes, and coordinator instance advance around frozen workflow snapshots.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00

104 lines
2.7 KiB
Go

package workflowdef
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/jackc/pgx/v5/pgxpool"
"chat-agent-system/internal/storage"
)
var officialSeedMeta = map[string]struct {
Name string
Description string
Domain string
}{
OfficialKeyMain: {
Name: "商务对接流程",
Description: "V0.1 需求摸底 → V0.5 方案与可行性 → V1.0 商务报价(7 个受控文档)",
Domain: "medical_device",
},
OfficialKeyProductManager: {
Name: "智能产品经理流程",
Description: "基于项目上下文独立生成系统需求规格书",
Domain: "medical_device",
},
OfficialKeyTestManager: {
Name: "智能测试工程师流程",
Description: "基于项目上下文独立生成系统验证方案及计划",
Domain: "medical_device",
},
}
// BootstrapSeeds 幂等导入模板与三正式 v2 工作流;非正式定义标记为不可选。
func BootstrapSeeds(ctx context.Context, pool *pgxpool.Pool, cas *storage.CAS, templatesDir string, publishedBy int64) error {
if pool == nil || !TablesReady(ctx, pool) {
return nil
}
store := NewStore(pool)
svc := NewService(pool, cas)
if templatesDir == "" {
templatesDir = "templates/docs"
}
entries, err := os.ReadDir(templatesDir)
if err != nil {
return nil
}
for _, ent := range entries {
if ent.IsDir() || !strings.HasSuffix(strings.ToLower(ent.Name()), ".md") {
continue
}
key := strings.TrimSuffix(ent.Name(), filepath.Ext(ent.Name()))
data, readErr := os.ReadFile(filepath.Join(templatesDir, ent.Name()))
if readErr != nil || len(data) == 0 {
continue
}
_, _ = svc.UploadTemplate(ctx, key, ent.Name(), data, ent.Name(), publishedBy)
}
for _, key := range OfficialWorkflowKeys() {
meta := officialSeedMeta[key]
filename := V2ManifestFiles[key]
def, loadErr := LoadManifestDefinition(filename)
if loadErr != nil {
return loadErr
}
normalizeManifestDefinition(&def)
if err := store.UpsertPublishedSeed(ctx, CreateDefinitionInput{
Key: key,
Name: meta.Name,
Description: meta.Description,
ProductDomain: meta.Domain,
Definition: def,
}, publishedBy); err != nil {
return err
}
}
return store.RetireNonOfficialDefinitions(ctx)
}
func normalizeManifestDefinition(def *VersionDefinition) {
if def == nil {
return
}
def.RequiredUpstreamWorkflow = ""
for i := range def.Stages {
for j := range def.Stages[i].DocTasks {
dt := &def.Stages[i].DocTasks[j]
if dt.CreatorConfigurable || dt.BlockingWhenEnabled || dt.DefaultEnabled {
continue
}
if dt.Required || dt.Blocking {
dt.CreatorConfigurable = true
dt.BlockingWhenEnabled = true
dt.DefaultEnabled = true
}
}
}
}