diff --git a/backend/internal/service/script_service.go b/backend/internal/service/script_service.go index 39cd9bb..22350e4 100644 --- a/backend/internal/service/script_service.go +++ b/backend/internal/service/script_service.go @@ -38,6 +38,7 @@ type treeNode struct { // BuildTree builds a directory tree from all scripts in the database. // Each script path is treated as a file path (e.g. "deploy/nginx/restart.sh"). +// Scripts with empty content and interpreter_id=0 are treated as folder placeholders. func (s *ScriptService) BuildTree() ([]repository.ScriptTreeNode, error) { scripts, err := s.Repo.ListScripts() if err != nil { @@ -49,10 +50,15 @@ func (s *ScriptService) BuildTree() ([]repository.ScriptTreeNode, error) { for _, sc := range scripts { parts := strings.Split(sc.Path, "/") + // A script with empty content and interpreter_id=0 is a folder placeholder + isPlaceholder := sc.Content == "" && sc.InterpreterID == 0 + // Walk through path parts, creating folders as needed currentMap := root for i, part := range parts { - isFile := i == len(parts)-1 + isLastPart := i == len(parts)-1 + isFile := isLastPart && !isPlaceholder + if _, exists := currentMap[part]; !exists { node := &treeNode{ name: part, @@ -70,6 +76,19 @@ func (s *ScriptService) BuildTree() ([]repository.ScriptTreeNode, error) { node.typ = "folder" } currentMap[part] = node + } else if isFile { + // Node already exists but was created as a folder (e.g. by another script's path). + // Convert it to a file if it was a folder placeholder. + existing := currentMap[part] + if existing.typ == "folder" { + id := sc.ID + content := sc.Content + interpreterID := sc.InterpreterID + existing.typ = "file" + existing.id = &id + existing.content = &content + existing.interpreterID = &interpreterID + } } currentMap = currentMap[part].children }