package model import ( "fmt" ) type Node struct { Issue Issue // Assuming Issue struct is imported or defined in the same package Children []*Node } // BuildTree builds a hierarchical tree of issues based on parent-child relationships. func BuildTree(issues []Issue) []*Node { nodeMap := make(map[int]*Node, len(issues)) for i := range issues { nodeMap[issues[i].ID] = &Node{Issue: issues[i]} } var roots []*Node for _, node := range nodeMap { if node.Issue.Parent == nil { roots = append(roots, node) } else { parent, ok := nodeMap[node.Issue.Parent.ID] if ok { parent.Children = append(parent.Children, node) } else { // Parent not in project scope → treat as root roots = append(roots, node) } } } return roots } // PrintTree prints the issue tree to standard output. func PrintTree(nodes []*Node, prefix string, isLast bool) { for i, node := range nodes { last := i == len(nodes)-1 connector := "├── " if last { connector = "└── " } parentInfo := "" if node.Issue.Parent != nil { parentInfo = fmt.Sprintf(" [parent: #%d]", node.Issue.Parent.ID) } fmt.Printf("%s%s#%d %s (%s)%s\n", prefix, connector, node.Issue.ID, node.Issue.Subject, node.Issue.Status.Title, parentInfo, ) childPrefix := prefix if last { childPrefix += " " } else { childPrefix += "│ " } PrintTree(node.Children, childPrefix, isLast) } }