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 }