228 lines
5.7 KiB
Go
228 lines
5.7 KiB
Go
// Path: Backend/internal/posixproj/projector_classify.go
|
|
|
|
package posixproj
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func deriveScope(relPath string, rootScope Scope) Scope {
|
|
scope := rootScope
|
|
parts := strings.Split(relPath, "/")
|
|
for _, part := range parts {
|
|
switch {
|
|
case strings.HasPrefix(part, "department-"):
|
|
scope.DepartmentSlug = strings.TrimPrefix(part, "department-")
|
|
case strings.HasPrefix(part, "team-"):
|
|
scope.TeamSlug = strings.TrimPrefix(part, "team-")
|
|
case strings.HasPrefix(part, "project-"):
|
|
scope.ProjectSlug = strings.TrimPrefix(part, "project-")
|
|
case strings.HasPrefix(part, "personal-"):
|
|
scope.PersonalSlug = strings.TrimPrefix(part, "personal-")
|
|
}
|
|
}
|
|
return scope
|
|
}
|
|
|
|
func classifyPath(relPath string, isDir bool) (logicalType, fileRole string) {
|
|
parts := strings.Split(relPath, "/")
|
|
name := parts[len(parts)-1]
|
|
ext := strings.ToLower(filepath.Ext(name))
|
|
structuredRole := strings.TrimSuffix(name, filepath.Ext(name))
|
|
if !isDir {
|
|
fileRole = structuredRole
|
|
}
|
|
|
|
hasChildrenAncestor := pathContainsSegment(parts, "children")
|
|
hasTreeAncestor := pathContainsSegment(parts, "tree")
|
|
parentName := ""
|
|
if len(parts) >= 2 {
|
|
parentName = parts[len(parts)-2]
|
|
}
|
|
|
|
switch {
|
|
case !isDir && structuredRole == "settings" && len(parts) == 1 && ext == ".cbor":
|
|
return "tenant", "settings"
|
|
case !isDir && structuredRole == "layout" && len(parts) == 1 && ext == ".cbor":
|
|
return "tenant", "layout"
|
|
case len(parts) >= 1 && parts[0] == "catalog":
|
|
if isDir {
|
|
if len(parts) == 1 {
|
|
return "catalog", ""
|
|
}
|
|
if len(parts) >= 2 && parts[1] == "packs" {
|
|
if len(parts) == 2 {
|
|
return "catalog_packs", ""
|
|
}
|
|
if len(parts) == 3 {
|
|
return "catalog_pack", ""
|
|
}
|
|
if len(parts) >= 4 && parts[3] == "entries" {
|
|
return "catalog_pack_entries", ""
|
|
}
|
|
return "catalog_entry", ""
|
|
}
|
|
if len(parts) >= 2 && parts[1] == "standalone" {
|
|
if len(parts) == 2 {
|
|
return "catalog_standalone", ""
|
|
}
|
|
return "catalog_entry", ""
|
|
}
|
|
}
|
|
return "catalog", fileRole
|
|
case len(parts) >= 2 && parts[0] == "departments" && strings.HasPrefix(parts[1], "department-"):
|
|
if isDir {
|
|
if len(parts) == 2 {
|
|
return "department", ""
|
|
}
|
|
if len(parts) == 3 && parts[2] == "teams" {
|
|
return "department_teams", ""
|
|
}
|
|
if len(parts) >= 4 && strings.HasPrefix(parts[3], "team-") {
|
|
return "team", ""
|
|
}
|
|
}
|
|
if len(parts) >= 4 && strings.HasPrefix(parts[3], "team-") {
|
|
return "team", fileRole
|
|
}
|
|
return "department", fileRole
|
|
case len(parts) >= 2 && parts[0] == "projects" && strings.HasPrefix(parts[1], "project-"):
|
|
if isDir {
|
|
if strings.HasPrefix(name, "project-") {
|
|
return "project", ""
|
|
}
|
|
if name == "children" {
|
|
return "project_children", ""
|
|
}
|
|
if name == "tree" {
|
|
return "project_tree", ""
|
|
}
|
|
if hasChildrenAncestor && strings.HasPrefix(name, "folder-") {
|
|
return "hierarchy_folder", ""
|
|
}
|
|
if hasTreeAncestor && strings.HasPrefix(name, "folder-") {
|
|
return "hierarchy_folder", ""
|
|
}
|
|
if hasTreeAncestor && strings.HasPrefix(name, "item-") {
|
|
return "item", ""
|
|
}
|
|
}
|
|
if hasChildrenAncestor && strings.HasPrefix(parentName, "folder-") {
|
|
return "hierarchy_folder", fileRole
|
|
}
|
|
if hasTreeAncestor {
|
|
if strings.HasPrefix(parentName, "item-") {
|
|
return "item", fileRole
|
|
}
|
|
if strings.HasPrefix(parentName, "folder-") {
|
|
return "hierarchy_folder", fileRole
|
|
}
|
|
}
|
|
return "project", fileRole
|
|
case len(parts) >= 1 && parts[0] == "users":
|
|
if isDir {
|
|
if len(parts) == 1 {
|
|
return "users", ""
|
|
}
|
|
if len(parts) == 2 && parts[1] == "personals" {
|
|
return "personals", ""
|
|
}
|
|
if len(parts) >= 3 && parts[1] == "personals" && strings.HasPrefix(parts[2], "personal-") {
|
|
return "personal", ""
|
|
}
|
|
if strings.Contains(relPath, "/tree/") || strings.HasSuffix(relPath, "/tree") {
|
|
if strings.HasPrefix(name, "folder-") {
|
|
return "folder", ""
|
|
}
|
|
if strings.HasPrefix(name, "item-") {
|
|
return "item", ""
|
|
}
|
|
}
|
|
}
|
|
if len(parts) >= 3 && parts[1] == "personals" && strings.HasPrefix(parts[2], "personal-") {
|
|
if strings.Contains(relPath, "/tree/") {
|
|
if strings.HasPrefix(parts[len(parts)-2], "item-") {
|
|
return "item", fileRole
|
|
}
|
|
if strings.HasPrefix(parts[len(parts)-2], "folder-") {
|
|
return "folder", fileRole
|
|
}
|
|
}
|
|
return "personal", fileRole
|
|
}
|
|
return "users", fileRole
|
|
default:
|
|
if isDir {
|
|
return "directory", ""
|
|
}
|
|
return "file", fileRole
|
|
}
|
|
}
|
|
|
|
func pathContainsSegment(parts []string, target string) bool {
|
|
for _, part := range parts {
|
|
if part == target {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func projectionParentPath(relPath string) *string {
|
|
if relPath == "" || relPath == rootProjectionPath {
|
|
return nil
|
|
}
|
|
parent := filepath.ToSlash(filepath.Dir(relPath))
|
|
if parent == "." || parent == "" {
|
|
root := rootProjectionPath
|
|
return &root
|
|
}
|
|
return &parent
|
|
}
|
|
|
|
func inferredResourceSlug(logicalType string, scope Scope) string {
|
|
switch logicalType {
|
|
case "department":
|
|
return scope.DepartmentSlug
|
|
case "team":
|
|
return scope.TeamSlug
|
|
case "project":
|
|
return scope.ProjectSlug
|
|
case "personal":
|
|
return scope.PersonalSlug
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func parentEntityName(logicalType string, scope Scope) string {
|
|
switch logicalType {
|
|
case "department":
|
|
return scope.DepartmentSlug
|
|
case "team":
|
|
return scope.TeamSlug
|
|
case "project":
|
|
return scope.ProjectSlug
|
|
case "personal":
|
|
return scope.PersonalSlug
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func stringValue(value any) string {
|
|
stringValue, _ := value.(string)
|
|
return strings.TrimSpace(stringValue)
|
|
}
|
|
|
|
func firstNonEmpty(values ...string) string {
|
|
for _, value := range values {
|
|
trimmed := strings.TrimSpace(value)
|
|
if trimmed != "" {
|
|
return trimmed
|
|
}
|
|
}
|
|
return ""
|
|
}
|