Files
Agent-System/internal/workflowdef/bootstrap.go
T
weichenandCursor 37b1aaa3ae feat(rdev): add medical design-control workflow (13 stages / 60 docs)
Seed rdev.v2.json, rd_ templates, catalog policy (order 40), squad
kind orchestration, and hard precheck requiring completed main (CDO).
Includes StageKey dynamicization from P0 and docs for P2–P4 skeleton.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 09:46:26 +00:00

119 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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",
},
OfficialKeyRDev: {
Name: "研发设计控制流程",
Description: "ISO 13485 设计控制:13 阶段 / 60 受控文档(DHF/DMR)",
Domain: "medical_device",
},
OfficialKeySoftwareBootstrap: {
Name: "软件项目自举流程",
Description: "S0–S4:章程、现状、需求、架构、风险、路线与就绪评审(无医疗语义)",
Domain: "non_medical_software",
},
OfficialKeySoftwareDelivery: {
Name: "软件交付迭代流程",
Description: "D0–D4:变更定义、实施证据、验证、发布与复盘(可重复实例)",
Domain: "non_medical_software",
},
}
// 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
}
}
}
}