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>
157 lines
4.8 KiB
Go
157 lines
4.8 KiB
Go
package projectworkflow
|
||
|
||
import "sync"
|
||
|
||
// Definition 工作流静态规范与契约定义
|
||
type Definition struct {
|
||
Key string `json:"key"`
|
||
Name string `json:"name"`
|
||
Description string `json:"description"`
|
||
StageKey string `json:"stage_key"`
|
||
TaskKey string `json:"task_key"`
|
||
RequiredUpstreamWorkflow string `json:"required_upstream_workflow,omitempty"`
|
||
OutputDocType string `json:"output_doc_type"`
|
||
OutputDocTitle string `json:"output_doc_title"`
|
||
Enabled bool `json:"enabled"`
|
||
}
|
||
|
||
// Catalog 工作流目录接口
|
||
type Catalog interface {
|
||
Get(workflowKey string) (*Definition, bool)
|
||
List() []*Definition
|
||
Validate() error
|
||
}
|
||
|
||
type memoryCatalog struct {
|
||
mu sync.RWMutex
|
||
definitions map[string]*Definition
|
||
order []string
|
||
}
|
||
|
||
// NewDefaultCatalog 创建默认工作流目录(医疗四 + 软件自举/交付)
|
||
func NewDefaultCatalog() Catalog {
|
||
c := &memoryCatalog{
|
||
definitions: make(map[string]*Definition),
|
||
order: []string{"main", "product_manager", "test_manager", "rdev", "software_bootstrap", "software_delivery"},
|
||
}
|
||
|
||
c.definitions["main"] = &Definition{
|
||
Key: "main",
|
||
Name: "商务与研发综合主线",
|
||
Description: "覆盖从 V0.1 分诊到 V0.6 阶段评审的全流程智能体编排与商务研发主干协同",
|
||
StageKey: "main",
|
||
TaskKey: "main",
|
||
OutputDocType: "main_proposal",
|
||
OutputDocTitle: "商务研发综合方案",
|
||
Enabled: true,
|
||
}
|
||
|
||
c.definitions["product_manager"] = &Definition{
|
||
Key: "product_manager",
|
||
Name: "智能产品经理",
|
||
Description: "基于用户需求或项目上下文深度提炼,生成高可靠、可追溯的系统需求规格书",
|
||
StageKey: "system_reqs",
|
||
TaskKey: "system_reqs",
|
||
OutputDocType: "system_reqs",
|
||
OutputDocTitle: "系统需求规格书",
|
||
Enabled: true,
|
||
}
|
||
|
||
c.definitions["test_manager"] = &Definition{
|
||
Key: "test_manager",
|
||
Name: "智能测试经理",
|
||
Description: "依赖产品经理已批准的系统需求规格书,生成全覆盖、满足法规要求的系统验证方案及计划",
|
||
StageKey: "system_test_plan",
|
||
TaskKey: "test_manager",
|
||
RequiredUpstreamWorkflow: "product_manager",
|
||
OutputDocType: "system_test_plan",
|
||
OutputDocTitle: "系统验证方案及计划",
|
||
Enabled: true,
|
||
}
|
||
|
||
c.definitions["rdev"] = &Definition{
|
||
Key: "rdev",
|
||
Name: "研发设计控制流程",
|
||
Description: "ISO 13485 设计控制:13 阶段 / 60 受控文档(DHF/DMR)",
|
||
StageKey: "RD01_planning",
|
||
TaskKey: "rd_proposal",
|
||
OutputDocType: "rd_proposal",
|
||
OutputDocTitle: "项目建议书",
|
||
Enabled: true,
|
||
}
|
||
|
||
c.definitions["software_bootstrap"] = &Definition{
|
||
Key: "software_bootstrap",
|
||
Name: "软件项目自举流程",
|
||
Description: "S0–S4:章程、现状、需求、架构、风险、路线与就绪评审",
|
||
StageKey: "S0_boundary",
|
||
TaskKey: "software_charter",
|
||
OutputDocType: "software_charter",
|
||
OutputDocTitle: "项目章程",
|
||
Enabled: true,
|
||
}
|
||
|
||
c.definitions["software_delivery"] = &Definition{
|
||
Key: "software_delivery",
|
||
Name: "软件交付迭代流程",
|
||
Description: "D0–D4:变更定义、实施证据、验证、发布与复盘",
|
||
StageKey: "D0_change_definition",
|
||
TaskKey: "change_brief",
|
||
OutputDocType: "change_brief",
|
||
OutputDocTitle: "变更简报",
|
||
Enabled: true,
|
||
}
|
||
|
||
return c
|
||
}
|
||
|
||
// WorkflowKeysForProductDomain returns the catalog keys to mount at create time.
|
||
// Empty domain keeps the full catalog (legacy medical create).
|
||
func WorkflowKeysForProductDomain(domain string) []string {
|
||
switch domain {
|
||
case "non_medical_software":
|
||
return []string{"software_bootstrap", "software_delivery"}
|
||
case "medical_device":
|
||
return []string{"main", "product_manager", "test_manager", "rdev"}
|
||
default:
|
||
return nil
|
||
}
|
||
}
|
||
|
||
func (c *memoryCatalog) Get(workflowKey string) (*Definition, bool) {
|
||
c.mu.RLock()
|
||
defer c.mu.RUnlock()
|
||
d, ok := c.definitions[workflowKey]
|
||
if !ok {
|
||
return nil, false
|
||
}
|
||
cpy := *d
|
||
return &cpy, true
|
||
}
|
||
|
||
func (c *memoryCatalog) List() []*Definition {
|
||
c.mu.RLock()
|
||
defer c.mu.RUnlock()
|
||
list := make([]*Definition, 0, len(c.order))
|
||
for _, key := range c.order {
|
||
if d, ok := c.definitions[key]; ok {
|
||
cpy := *d
|
||
list = append(list, &cpy)
|
||
}
|
||
}
|
||
return list
|
||
}
|
||
|
||
func (c *memoryCatalog) Validate() error {
|
||
c.mu.RLock()
|
||
defer c.mu.RUnlock()
|
||
for _, def := range c.definitions {
|
||
if def.RequiredUpstreamWorkflow != "" {
|
||
if _, ok := c.definitions[def.RequiredUpstreamWorkflow]; !ok {
|
||
return ErrWorkflowNotFound
|
||
}
|
||
}
|
||
}
|
||
return nil
|
||
}
|