Files
Agent-System/internal/workflowdef/bootstrap.go
T
weichenandCursor edffe74009 feat(db): add workflow definitions, versions, and template asset tables
Introduce Phase 2 IAM-adjacent schema for versioned workflow definitions,
template assets/versions, and workflow_defs permissions seed.

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

140 lines
5.4 KiB
Go

package workflowdef
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/jackc/pgx/v5/pgxpool"
"chat-agent-system/internal/projectworkflow"
"chat-agent-system/internal/storage"
)
func legacySingleStage(key, name, desc, stageKey, taskKey, docType, docTitle, upstream string) CreateDefinitionInput {
return CreateDefinitionInput{
Key: key,
Name: name,
Description: desc,
ProductDomain: "medical_device",
Definition: VersionDefinition{
SchemaVersion: 1,
RequiredUpstreamWorkflow: upstream,
Stages: []StageDef{{
Key: stageKey, Name: stageKey, Position: 0,
DocTasks: []DocTaskDef{{
Key: taskKey, Title: docTitle, Required: true, Blocking: true, DefaultEnabled: true,
OutputDocType: docType, OutputDocTitle: docTitle,
TemplateAssetKey: taskKey, TemplateVersion: 1,
}},
}},
},
}
}
// BootstrapSeeds 幂等导入静态 catalog、首批行业工作流与 templates/docs。
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)
}
seeds := []CreateDefinitionInput{
legacySingleStage("main", "商务与研发综合主线", "V0.1 分诊到 V0.6 阶段评审", "main", "main", "main_proposal", "商务研发综合方案", ""),
legacySingleStage("product_manager", "智能产品经理", "系统需求规格书生成", "system_reqs", "system_reqs", "system_reqs", "系统需求规格书", ""),
legacySingleStage("test_manager", "智能测试经理", "系统验证方案及计划", "system_test_plan", "test_manager", "system_test_plan", "系统验证方案及计划", "product_manager"),
medicalDeviceWorkflow(),
nonMedicalSoftwareWorkflow(),
}
for _, seed := range seeds {
if err := store.UpsertPublishedSeed(ctx, seed, publishedBy); err != nil {
return err
}
}
return nil
}
func medicalDeviceWorkflow() CreateDefinitionInput {
return CreateDefinitionInput{
Key: "medical_device_development",
Name: "医疗器械研发",
Description: "商务摸底 → 需求策划 → 设计开发 → 验证确认 → 设计转移",
ProductDomain: "medical_device",
Definition: VersionDefinition{
SchemaVersion: 1,
Stages: []StageDef{
stage("biz_intake", "商务摸底", 0, doc("intake", "客户需求采集", "intake", "客户需求采集表")),
stage("req_planning", "需求与法规策划", 1, doc("system_reqs", "系统需求规格书", "system_reqs", "系统需求规格书")),
stage("design_dev", "设计开发", 2, doc("prelim_design", "初步设计", "prelim_design", "初步设计文档")),
stage("verification", "设计验证/确认", 3, doc("test_manager", "系统验证方案", "system_test_plan", "系统验证方案及计划")),
stage("transfer", "设计转移/发布", 4, doc("feasibility_reg", "法规可行性", "feasibility_reg", "法规可行性评估")),
},
},
}
}
func nonMedicalSoftwareWorkflow() CreateDefinitionInput {
return CreateDefinitionInput{
Key: "non_medical_software",
Name: "非医疗纯软件",
Description: "机会范围 → 需求 → 架构 → 实现 → 测试验收 → 发布复盘",
ProductDomain: "non_medical_software",
Definition: VersionDefinition{
SchemaVersion: 1,
Stages: []StageDef{
stage("opportunity", "机会与范围", 0, doc("intake", "范围说明", "scope_doc", "项目范围说明")),
stage("requirements", "产品需求", 1, doc("user_requirements", "用户需求", "user_requirements", "用户需求说明")),
stage("architecture", "架构与计划", 2, doc("feasibility_dev", "技术可行性", "feasibility_dev", "技术可行性分析")),
stage("implementation", "实现", 3, doc("prelim_design", "架构设计", "architecture_design", "架构设计文档")),
stage("testing", "测试与验收", 4, doc("test_manager", "测试计划", "test_plan", "测试计划")),
stage("release", "发布复盘", 5, doc("research", "发布复盘", "release_review", "发布复盘报告")),
},
},
}
}
func stage(key, name string, pos int, tasks ...DocTaskDef) StageDef {
return StageDef{Key: key, Name: name, Position: pos, DocTasks: tasks}
}
func doc(key, title, docType, docTitle string) DocTaskDef {
return DocTaskDef{
Key: key, Title: title, Required: true, Blocking: true, DefaultEnabled: true,
TemplateAssetKey: key, TemplateVersion: 1,
OutputDocType: docType, OutputDocTitle: docTitle,
}
}
// SeedFromMemoryCatalog 将内存 catalog 转为种子(测试用)。
func SeedFromMemoryCatalog(cat projectworkflow.Catalog) []CreateDefinitionInput {
if cat == nil {
return nil
}
out := make([]CreateDefinitionInput, 0)
for _, d := range cat.List() {
out = append(out, legacySingleStage(d.Key, d.Name, d.Description, d.StageKey, d.TaskKey, d.OutputDocType, d.OutputDocTitle, d.RequiredUpstreamWorkflow))
}
return out
}