feat: complete SOP execution workflow
This commit is contained in:
113
scripts/seed-pet-doctor/main_test.go
Normal file
113
scripts/seed-pet-doctor/main_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
|
||||
"git.iwork-ai.com/xdc/iqudo-top1/internal/sop"
|
||||
"gorm.io/datatypes"
|
||||
)
|
||||
|
||||
func TestPetDoctorSOPPassesPublishValidation(t *testing.T) {
|
||||
fields := petFieldModels()
|
||||
knowledgeIDs := map[string]uint64{
|
||||
"线上问诊边界": 1,
|
||||
"急症红旗征象": 2,
|
||||
"问诊用药安全原则": 3,
|
||||
"观察与复诊提示": 4,
|
||||
}
|
||||
nodes := petNodeModels(petNodes(knowledgeIDs))
|
||||
edges := petEdgeModels(petEdges())
|
||||
if len(fields) != 47 || len(nodes) != 21 || len(edges) != 21 {
|
||||
t.Fatalf("unexpected definition size: fields=%d nodes=%d edges=%d", len(fields), len(nodes), len(edges))
|
||||
}
|
||||
|
||||
problems := sop.ValidateForPublish("start", nodes, edges, sop.ValidationContext{
|
||||
Fields: fields,
|
||||
PublishedKnowledgeCardIDs: map[uint64]bool{
|
||||
1: true,
|
||||
2: true,
|
||||
3: true,
|
||||
4: true,
|
||||
},
|
||||
})
|
||||
if len(problems) > 0 {
|
||||
t.Fatalf("pet doctor SOP should be publishable, got: %v", problems)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPetDoctorSOPHasBothRiskEscalations(t *testing.T) {
|
||||
nodes := petNodes(map[string]uint64{
|
||||
"线上问诊边界": 1,
|
||||
"急症红旗征象": 2,
|
||||
"问诊用药安全原则": 3,
|
||||
"观察与复诊提示": 4,
|
||||
})
|
||||
escalations := map[string]bool{}
|
||||
for _, node := range nodes {
|
||||
if node.Type == "escalate" {
|
||||
escalations[node.Key] = true
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"emergency_escalate", "medication_escalate"} {
|
||||
if !escalations[key] {
|
||||
t.Fatalf("missing risk escalation node %s", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSameJSONIgnoresObjectOrderAndWhitespace(t *testing.T) {
|
||||
left := []byte(`{"standard_copy":"安全提示","risk_note":"立即就医"}`)
|
||||
right := []byte(`{ "risk_note": "立即就医", "standard_copy": "安全提示" }`)
|
||||
if !sameJSON(left, right) {
|
||||
t.Fatal("equivalent JSON objects should match")
|
||||
}
|
||||
}
|
||||
|
||||
func petFieldModels() []model.ScenarioField {
|
||||
definitions := petFieldDefinitions()
|
||||
fields := make([]model.ScenarioField, 0, len(definitions))
|
||||
for _, definition := range definitions {
|
||||
options, _ := json.Marshal(definition.Options)
|
||||
validation, _ := json.Marshal(definition.Validation)
|
||||
fields = append(fields, model.ScenarioField{
|
||||
FieldKey: definition.Key,
|
||||
FieldName: definition.Name,
|
||||
FieldType: definition.Type,
|
||||
Required: definition.Required,
|
||||
Options: datatypes.JSON(options),
|
||||
Validation: datatypes.JSON(validation),
|
||||
})
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func petNodeModels(definitions []nodeDefinition) []model.SOPNode {
|
||||
nodes := make([]model.SOPNode, 0, len(definitions))
|
||||
for _, definition := range definitions {
|
||||
config, _ := json.Marshal(definition.Config)
|
||||
nodes = append(nodes, model.SOPNode{
|
||||
NodeKey: definition.Key,
|
||||
Type: definition.Type,
|
||||
Title: definition.Title,
|
||||
Content: definition.Content,
|
||||
Config: datatypes.JSON(config),
|
||||
})
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func petEdgeModels(definitions []edgeDefinition) []model.SOPEdge {
|
||||
edges := make([]model.SOPEdge, 0, len(definitions))
|
||||
for _, definition := range definitions {
|
||||
condition, _ := json.Marshal(definition.Condition)
|
||||
edges = append(edges, model.SOPEdge{
|
||||
SourceNodeKey: definition.Source,
|
||||
TargetNodeKey: definition.Target,
|
||||
Condition: datatypes.JSON(condition),
|
||||
Priority: definition.Priority,
|
||||
})
|
||||
}
|
||||
return edges
|
||||
}
|
||||
Reference in New Issue
Block a user