package knowledge import "strings" type DerivedTags struct { Relevance []string `json:"relevance"` Recency []string `json:"recency"` } type Evidence struct { URL string `json:"url"` Snippet string `json:"snippet"` Query string `json:"query,omitempty"` } type Node struct { ID string `json:"id"` Label string `json:"label"` NodeKind string `json:"nodeKind"` // pain | knowledge | cause | symptom Type string `json:"type"` // core | cause | symptom | mechanism Layer int `json:"layer"` Relation string `json:"relation,omitempty"` PlacementValue string `json:"placementValue,omitempty"` // 為何與產品置入相關(完整句子) ProductFitScore int `json:"productFitScore"` SelectedForScan bool `json:"selectedForScan"` PatrolRelevance []string `json:"patrolRelevance,omitempty"` PatrolRecency []string `json:"patrolRecency,omitempty"` Evidence []Evidence `json:"evidence"` DerivedTags DerivedTags `json:"derivedTags"` } type Edge struct { From string `json:"from"` To string `json:"to"` Relation string `json:"relation"` } type BraveSource struct { Query string `json:"query"` Snippet string `json:"snippet"` URL string `json:"url"` Title string `json:"title,omitempty"` } type Graph struct { Seed string `json:"seed"` Nodes []Node `json:"nodes"` Edges []Edge `json:"edges"` BraveSources []BraveSource `json:"braveSources"` PainTagCount int `json:"painTagCount"` } func IsPainNode(node Node) bool { switch strings.TrimSpace(node.NodeKind) { case "pain", "symptom", "cause": return true default: return false } } func CountPainTagCandidates(nodes []Node) int { count := 0 for _, node := range nodes { if !IsPainNode(node) { continue } if len(node.DerivedTags.Relevance) > 0 || len(node.DerivedTags.Recency) > 0 { count++ } } return count } func TotalTagCandidates(nodes []Node) int { count := 0 for _, node := range nodes { count += len(node.DerivedTags.Relevance) + len(node.DerivedTags.Recency) } return count } func NodeByID(nodes []Node, id string) (Node, bool) { id = strings.TrimSpace(id) for _, node := range nodes { if node.ID == id { return node, true } } return Node{}, false }