Refactor: improve backend modularity
This commit is contained in:
@@ -0,0 +1,491 @@
|
||||
// Path: Backend/internal/bootstrap/project_mutations.go
|
||||
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (service *Service) CreateProjectFolder(ctx context.Context, input CreateProjectFolderInput) (CreateProjectFolderResult, error) {
|
||||
return service.createProjectHierarchyFolder(ctx, input, projectHierarchyRootPath, service.createProjectHierarchyFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) CreateProjectTreeFolder(ctx context.Context, input CreateProjectFolderInput) (CreateProjectFolderResult, error) {
|
||||
return service.createProjectHierarchyFolder(ctx, input, projectTreeRootPath, service.createProjectTreeFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) DeleteProjectFolder(ctx context.Context, input DeleteProjectFolderInput) (DeleteProjectFolderResult, error) {
|
||||
return service.deleteProjectHierarchyFolder(ctx, input, projectHierarchyRootPath, service.deleteProjectHierarchyFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) DeleteProjectTreeFolder(ctx context.Context, input DeleteProjectFolderInput) (DeleteProjectFolderResult, error) {
|
||||
return service.deleteProjectHierarchyFolder(ctx, input, projectTreeRootPath, service.deleteProjectTreeFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) RenameProjectFolder(ctx context.Context, input RenameProjectFolderInput) (RenameProjectFolderResult, error) {
|
||||
return service.renameProjectHierarchyFolder(ctx, input, projectHierarchyRootPath, service.renameProjectHierarchyFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) RenameProjectTreeFolder(ctx context.Context, input RenameProjectFolderInput) (RenameProjectFolderResult, error) {
|
||||
return service.renameProjectHierarchyFolder(ctx, input, projectTreeRootPath, service.renameProjectTreeFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) MoveProjectFolder(ctx context.Context, input MoveProjectFolderInput) (MoveProjectFolderResult, error) {
|
||||
return service.moveProjectHierarchyFolder(ctx, input, projectHierarchyRootPath, service.moveProjectHierarchyFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) MoveProjectTreeFolder(ctx context.Context, input MoveProjectFolderInput) (MoveProjectFolderResult, error) {
|
||||
return service.moveProjectHierarchyFolder(ctx, input, projectTreeRootPath, service.moveProjectTreeFolderOnDisk)
|
||||
}
|
||||
|
||||
func (service *Service) CreateProjectTreeItem(ctx context.Context, input CreateProjectItemInput) (CreateProjectItemResult, error) {
|
||||
return service.createProjectTreeItem(ctx, input, projectTreeRootPath)
|
||||
}
|
||||
|
||||
func (service *Service) DeleteProjectTreeItem(ctx context.Context, input DeleteProjectItemInput) (DeleteProjectItemResult, error) {
|
||||
return service.deleteProjectTreeItem(ctx, input, projectTreeRootPath)
|
||||
}
|
||||
|
||||
func (service *Service) MoveProjectTreeItem(ctx context.Context, input MoveProjectItemInput) (MoveProjectItemResult, error) {
|
||||
return service.moveProjectTreeItem(ctx, input, projectTreeRootPath)
|
||||
}
|
||||
|
||||
func (service *Service) createProjectHierarchyFolder(
|
||||
ctx context.Context,
|
||||
input CreateProjectFolderInput,
|
||||
rootPath func(projectSlug string) string,
|
||||
createOnDisk func(projectSlug, parentFolderPath, name string) (string, string, error),
|
||||
) (CreateProjectFolderResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
currentFolders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
parentOrderID := ""
|
||||
trimmedParentFolderPath := strings.TrimSpace(input.ParentFolderPath)
|
||||
if trimmedParentFolderPath != "" {
|
||||
parentFolder, found := findProjectHierarchyFolderByPath(currentFolders, trimmedParentFolderPath)
|
||||
if !found {
|
||||
return CreateProjectFolderResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
parentOrderID = parentFolder.ID
|
||||
}
|
||||
|
||||
createdPath, _, err := createOnDisk(project.Slug, strings.TrimSpace(input.ParentFolderPath), input.Name)
|
||||
if err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
createdFolder, ok := findProjectHierarchyFolderByPath(folders, createdPath)
|
||||
if !ok {
|
||||
return CreateProjectFolderResult{}, fmt.Errorf("created project folder missing from projection")
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
seedFolderOrderParent(folderOrder, currentFolders, parentOrderID)
|
||||
insertFolderOrder(folderOrder, parentOrderID, createdFolder.ID, len(folderOrderChildren(folderOrder, parentOrderID)))
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err = service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
createdFolder, ok = findProjectHierarchyFolderByPath(folders, createdPath)
|
||||
if !ok {
|
||||
return CreateProjectFolderResult{}, fmt.Errorf("created project folder missing from ordered projection")
|
||||
}
|
||||
|
||||
return CreateProjectFolderResult{ProjectID: project.ID, CreatedFolder: createdFolder, Folders: folders}, nil
|
||||
}
|
||||
|
||||
func (service *Service) deleteProjectHierarchyFolder(
|
||||
ctx context.Context,
|
||||
input DeleteProjectFolderInput,
|
||||
rootPath func(projectSlug string) string,
|
||||
deleteOnDisk func(projectSlug, folderPath string) (string, error),
|
||||
) (DeleteProjectFolderResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
currentFolders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
deletedFolder, found := findProjectHierarchyFolderByPath(currentFolders, strings.TrimSpace(input.FolderPath))
|
||||
if !found {
|
||||
return DeleteProjectFolderResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
|
||||
deletedFolderPath, err := deleteOnDisk(project.Slug, input.FolderPath)
|
||||
if err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
if _, found := findProjectHierarchyFolderByPath(folders, deletedFolderPath); found {
|
||||
return DeleteProjectFolderResult{}, fmt.Errorf("deleted project folder still present in projection")
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
removeFolderOrder(folderOrder, deletedFolder.ID)
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err = service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
return DeleteProjectFolderResult{ProjectID: project.ID, DeletedFolderStableID: deletedFolder.ID, DeletedFolderPath: deletedFolderPath, Folders: folders}, nil
|
||||
}
|
||||
|
||||
func (service *Service) renameProjectHierarchyFolder(
|
||||
ctx context.Context,
|
||||
input RenameProjectFolderInput,
|
||||
rootPath func(projectSlug string) string,
|
||||
renameOnDisk func(projectSlug, folderPath, name string) (string, string, error),
|
||||
) (RenameProjectFolderResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return RenameProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
previousFolderPath, renamedFolderPath, err := renameOnDisk(project.Slug, input.FolderPath, input.Name)
|
||||
if err != nil {
|
||||
return RenameProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return RenameProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return RenameProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
renamedFolder, found := findProjectHierarchyFolderByPath(folders, renamedFolderPath)
|
||||
if !found {
|
||||
return RenameProjectFolderResult{}, fmt.Errorf("renamed project folder missing from projection")
|
||||
}
|
||||
|
||||
if _, found := findProjectHierarchyFolderByPath(folders, previousFolderPath); found {
|
||||
return RenameProjectFolderResult{}, fmt.Errorf("previous project folder path still present in projection")
|
||||
}
|
||||
|
||||
return RenameProjectFolderResult{ProjectID: project.ID, PreviousFolderStableID: renamedFolder.ID, PreviousFolderPath: previousFolderPath, RenamedFolder: renamedFolder, Folders: folders}, nil
|
||||
}
|
||||
|
||||
func (service *Service) moveProjectHierarchyFolder(
|
||||
ctx context.Context,
|
||||
input MoveProjectFolderInput,
|
||||
rootPath func(projectSlug string) string,
|
||||
moveOnDisk func(projectSlug, folderPath, parentFolderPath string) (string, string, error),
|
||||
) (MoveProjectFolderResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
currentFolders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
currentFolder, found := findProjectHierarchyFolderByPath(currentFolders, strings.TrimSpace(input.FolderPath))
|
||||
if !found {
|
||||
return MoveProjectFolderResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
|
||||
movedFolderStableID := currentFolder.ID
|
||||
providedFolderStableID := strings.TrimSpace(input.FolderStableID)
|
||||
if providedFolderStableID != "" && providedFolderStableID != movedFolderStableID {
|
||||
return MoveProjectFolderResult{}, ErrInvalidProjectFolderMove
|
||||
}
|
||||
|
||||
parentOrderID := ""
|
||||
trimmedParentFolderPath := strings.TrimSpace(input.ParentFolderPath)
|
||||
providedParentStableID := strings.TrimSpace(input.ParentStableID)
|
||||
if trimmedParentFolderPath != "" {
|
||||
parentFolder, found := findProjectHierarchyFolderByPath(currentFolders, trimmedParentFolderPath)
|
||||
if !found {
|
||||
return MoveProjectFolderResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
parentOrderID = parentFolder.ID
|
||||
if providedParentStableID != "" && providedParentStableID != parentOrderID {
|
||||
return MoveProjectFolderResult{}, ErrInvalidProjectFolderMove
|
||||
}
|
||||
} else if providedParentStableID != "" {
|
||||
return MoveProjectFolderResult{}, ErrInvalidProjectFolderMove
|
||||
}
|
||||
|
||||
previousFolderPath, movedFolderPath, err := moveOnDisk(project.Slug, input.FolderPath, input.ParentFolderPath)
|
||||
if err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err := service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
movedFolder, found := findProjectHierarchyFolderByPath(folders, movedFolderPath)
|
||||
if !found {
|
||||
return MoveProjectFolderResult{}, fmt.Errorf("moved project folder missing from projection")
|
||||
}
|
||||
|
||||
if previousFolderPath != movedFolderPath {
|
||||
if _, found := findProjectHierarchyFolderByPath(folders, previousFolderPath); found {
|
||||
return MoveProjectFolderResult{}, fmt.Errorf("previous project folder path still present in projection")
|
||||
}
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
seedFolderOrderParent(folderOrder, currentFolders, parentOrderID)
|
||||
removeFolderOrderReference(folderOrder, movedFolderStableID)
|
||||
removeFolderOrderReference(folderOrder, movedFolder.ID)
|
||||
insertFolderOrder(folderOrder, parentOrderID, movedFolder.ID, input.TargetIndex)
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
folders, err = service.getProjectHierarchyFoldersByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectFolderResult{}, err
|
||||
}
|
||||
|
||||
movedFolder, found = findProjectHierarchyFolderByPath(folders, movedFolderPath)
|
||||
if !found {
|
||||
return MoveProjectFolderResult{}, fmt.Errorf("moved project folder missing from ordered projection")
|
||||
}
|
||||
|
||||
return MoveProjectFolderResult{ProjectID: project.ID, PreviousFolderStableID: movedFolder.ID, PreviousFolderPath: previousFolderPath, MovedFolder: movedFolder, Folders: folders}, nil
|
||||
}
|
||||
|
||||
func (service *Service) createProjectTreeItem(ctx context.Context, input CreateProjectItemInput, rootPath func(projectSlug string) string) (CreateProjectItemResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
currentNodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
parentOrderID := ""
|
||||
trimmedParentFolderPath := strings.TrimSpace(input.ParentFolderPath)
|
||||
if trimmedParentFolderPath != "" {
|
||||
parentFolder, found := findProjectTreeFolderByPath(currentNodes, trimmedParentFolderPath)
|
||||
if !found {
|
||||
return CreateProjectItemResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
parentOrderID = parentFolder.ID
|
||||
}
|
||||
|
||||
createdPath, err := service.createProjectTreeItemOnDisk(project.Slug, trimmedParentFolderPath, input.Name, input.ItemType)
|
||||
if err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
createdItem, ok := findProjectTreeNodeByPath(nodes, createdPath)
|
||||
if !ok || createdItem.Kind != "item" {
|
||||
return CreateProjectItemResult{}, fmt.Errorf("created project item missing from projection")
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
seedProjectTreeOrderParent(folderOrder, currentNodes, parentOrderID)
|
||||
insertFolderOrder(folderOrder, parentOrderID, createdItem.ID, len(folderOrderChildren(folderOrder, parentOrderID)))
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err = service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return CreateProjectItemResult{}, err
|
||||
}
|
||||
|
||||
createdItem, ok = findProjectTreeNodeByPath(nodes, createdPath)
|
||||
if !ok || createdItem.Kind != "item" {
|
||||
return CreateProjectItemResult{}, fmt.Errorf("created project item missing from ordered projection")
|
||||
}
|
||||
|
||||
return CreateProjectItemResult{ProjectID: project.ID, CreatedItem: createdItem, Nodes: nodes}, nil
|
||||
}
|
||||
|
||||
func (service *Service) deleteProjectTreeItem(ctx context.Context, input DeleteProjectItemInput, rootPath func(projectSlug string) string) (DeleteProjectItemResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
currentNodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
deletedItem, found := findProjectTreeNodeByPath(currentNodes, strings.TrimSpace(input.ItemPath))
|
||||
if !found || deletedItem.Kind != "item" {
|
||||
return DeleteProjectItemResult{}, ErrProjectItemNotFound
|
||||
}
|
||||
|
||||
deletedItemPath, err := service.deleteProjectTreeItemOnDisk(project.Slug, input.ItemPath)
|
||||
if err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
if _, found := findProjectTreeNodeByPath(nodes, deletedItemPath); found {
|
||||
return DeleteProjectItemResult{}, fmt.Errorf("deleted project item still present in projection")
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
removeFolderOrderReference(folderOrder, deletedItem.ID)
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err = service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return DeleteProjectItemResult{}, err
|
||||
}
|
||||
|
||||
return DeleteProjectItemResult{ProjectID: project.ID, DeletedItemStableID: deletedItem.ID, DeletedItemPath: deletedItemPath, Nodes: nodes}, nil
|
||||
}
|
||||
|
||||
func (service *Service) moveProjectTreeItem(ctx context.Context, input MoveProjectItemInput, rootPath func(projectSlug string) string) (MoveProjectItemResult, error) {
|
||||
project, err := service.loadProjectByID(ctx, strings.TrimSpace(input.ProjectID))
|
||||
if err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
currentNodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
currentItem, found := findProjectTreeNodeByPath(currentNodes, strings.TrimSpace(input.ItemPath))
|
||||
if !found || currentItem.Kind != "item" {
|
||||
return MoveProjectItemResult{}, ErrProjectItemNotFound
|
||||
}
|
||||
|
||||
movedItemStableID := currentItem.ID
|
||||
providedItemStableID := strings.TrimSpace(input.ItemStableID)
|
||||
if providedItemStableID != "" && providedItemStableID != movedItemStableID {
|
||||
return MoveProjectItemResult{}, ErrInvalidProjectItemMove
|
||||
}
|
||||
|
||||
parentOrderID := ""
|
||||
trimmedParentFolderPath := strings.TrimSpace(input.ParentFolderPath)
|
||||
providedParentStableID := strings.TrimSpace(input.ParentStableID)
|
||||
if trimmedParentFolderPath != "" {
|
||||
parentFolder, found := findProjectTreeFolderByPath(currentNodes, trimmedParentFolderPath)
|
||||
if !found {
|
||||
return MoveProjectItemResult{}, ErrProjectFolderNotFound
|
||||
}
|
||||
parentOrderID = parentFolder.ID
|
||||
if providedParentStableID != "" && providedParentStableID != parentOrderID {
|
||||
return MoveProjectItemResult{}, ErrInvalidProjectItemMove
|
||||
}
|
||||
} else if providedParentStableID != "" {
|
||||
return MoveProjectItemResult{}, ErrInvalidProjectItemMove
|
||||
}
|
||||
|
||||
previousItemPath, movedItemPath, err := service.moveProjectTreeItemOnDisk(project.Slug, input.ItemPath, input.ParentFolderPath)
|
||||
if err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
if err := service.rebuildProjection(ctx); err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err := service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
movedItem, found := findProjectTreeNodeByPath(nodes, movedItemPath)
|
||||
if !found || movedItem.Kind != "item" {
|
||||
return MoveProjectItemResult{}, fmt.Errorf("moved project item missing from projection")
|
||||
}
|
||||
|
||||
if previousItemPath != movedItemPath {
|
||||
if _, found := findProjectTreeNodeByPath(nodes, previousItemPath); found {
|
||||
return MoveProjectItemResult{}, fmt.Errorf("previous project item path still present in projection")
|
||||
}
|
||||
}
|
||||
|
||||
folderOrder := service.readProjectFolderOrder(project.Slug, rootPath(project.Slug))
|
||||
seedProjectTreeOrderParent(folderOrder, currentNodes, parentOrderID)
|
||||
removeFolderOrderReference(folderOrder, movedItemStableID)
|
||||
removeFolderOrderReference(folderOrder, movedItem.ID)
|
||||
insertFolderOrder(folderOrder, parentOrderID, movedItem.ID, input.TargetIndex)
|
||||
if err := service.writeProjectFolderOrder(project.Slug, rootPath(project.Slug), folderOrder); err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
nodes, err = service.getProjectTreeNodesByRootPath(ctx, project.ID, rootPath)
|
||||
if err != nil {
|
||||
return MoveProjectItemResult{}, err
|
||||
}
|
||||
|
||||
movedItem, found = findProjectTreeNodeByPath(nodes, movedItemPath)
|
||||
if !found || movedItem.Kind != "item" {
|
||||
return MoveProjectItemResult{}, fmt.Errorf("moved project item missing from ordered projection")
|
||||
}
|
||||
|
||||
return MoveProjectItemResult{ProjectID: project.ID, PreviousItemStableID: movedItem.ID, PreviousItemPath: previousItemPath, MovedItem: movedItem, Nodes: nodes}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user