// Path: Backend/internal/bootstrap/project_disk_bootstrap.go package bootstrap import ( "fmt" "os" "path/filepath" "strings" ) func (service *Service) ensureBootstrapPOSIXSkeleton( installation InstallationRecord, admin AdminSummary, organization namedRecord, department namedRecord, team namedRecord, project namedRecord, ) error { rootPath := strings.TrimSpace(service.posixRoot) if rootPath == "" { return nil } if err := os.MkdirAll(rootPath, 0o755); err != nil { return fmt.Errorf("create POSIX root: %w", err) } if err := writeJSONFile(filepath.Join(rootPath, "settings.json"), map[string]any{ "installation": map[string]any{ "id": installation.ID, "name": installation.Name, "mode": installation.Mode, "access": installation.Access, "protocol": installation.Protocol, "host": installation.Host, "isBootstrapped": installation.IsBootstrapped, }, "organization": map[string]any{ "id": organization.ID, "name": organization.Name, "slug": organization.Slug, }, }); err != nil { return fmt.Errorf("write tenant settings.json: %w", err) } if err := writeJSONFile(filepath.Join(rootPath, "layout.json"), map[string]any{ "version": 1, "type": "tenant-layout", "home": map[string]any{ "defaultProjectSlug": project.Slug, }, }); err != nil { return fmt.Errorf("write tenant layout.json: %w", err) } if err := os.MkdirAll(filepath.Join(rootPath, "catalog", "packs"), 0o755); err != nil { return fmt.Errorf("create catalog packs root: %w", err) } if err := os.MkdirAll(filepath.Join(rootPath, "catalog", "standalone"), 0o755); err != nil { return fmt.Errorf("create catalog standalone root: %w", err) } departmentPath := filepath.Join(rootPath, "departments", slugDir("department", department.Slug)) teamPath := filepath.Join(departmentPath, "teams", slugDir("team", team.Slug)) projectPath := filepath.Join(rootPath, "projects", slugDir("project", project.Slug)) usersPath := filepath.Join(rootPath, "users") personalName := strings.TrimSpace(admin.DisplayName) if personalName == "" { personalName = defaultPersonalDisplayName } personalSlug := normalizePOSIXSlug(personalName) personalHomePath := filepath.Join(usersPath, "personals", slugDir("personal", personalSlug)) for _, dirPath := range []string{ departmentPath, teamPath, projectPath, filepath.Join(projectPath, "children"), filepath.Join(projectPath, "tree"), filepath.Join(usersPath, "personals"), personalHomePath, filepath.Join(personalHomePath, "tree"), } { if err := os.MkdirAll(dirPath, 0o755); err != nil { return fmt.Errorf("create POSIX directory %s: %w", dirPath, err) } } if err := writeJSONFile(filepath.Join(departmentPath, "settings.json"), map[string]any{ "id": department.ID, "name": department.Name, "slug": department.Slug, "type": "department", }); err != nil { return fmt.Errorf("write department settings.json: %w", err) } if err := writeJSONFile(filepath.Join(departmentPath, "users.json"), map[string]any{ "owners": []map[string]string{{ "id": admin.ID, "email": admin.Email, "displayName": admin.DisplayName, }}, }); err != nil { return fmt.Errorf("write department users.json: %w", err) } if err := writeJSONFile(filepath.Join(teamPath, "settings.json"), map[string]any{ "id": team.ID, "name": team.Name, "slug": team.Slug, "type": "team", }); err != nil { return fmt.Errorf("write team settings.json: %w", err) } if err := writeJSONFile(filepath.Join(teamPath, "users.json"), map[string]any{ "owners": []map[string]string{{ "id": admin.ID, "email": admin.Email, "displayName": admin.DisplayName, }}, }); err != nil { return fmt.Errorf("write team users.json: %w", err) } if err := writeJSONFile(filepath.Join(projectPath, "settings.json"), map[string]any{ "id": project.ID, "name": project.Name, "slug": project.Slug, "type": "project", }); err != nil { return fmt.Errorf("write project settings.json: %w", err) } if err := writeJSONFile(filepath.Join(projectPath, "home.json"), map[string]any{ "type": "project-home", "title": project.Name, }); err != nil { return fmt.Errorf("write project home.json: %w", err) } if err := writeJSONFile(filepath.Join(projectPath, "acl.json"), map[string]any{ "version": 1, "inherits": true, "rules": []any{}, }); err != nil { return fmt.Errorf("write project acl.json: %w", err) } if err := writeJSONFile(filepath.Join(usersPath, "settings.json"), map[string]any{ "primaryAdminId": admin.ID, }); err != nil { return fmt.Errorf("write users settings.json: %w", err) } if err := writeJSONFile(filepath.Join(usersPath, "data.json"), map[string]any{ "admins": []map[string]string{{ "id": admin.ID, "email": admin.Email, "displayName": admin.DisplayName, }}, }); err != nil { return fmt.Errorf("write users data.json: %w", err) } if err := writeJSONFile(filepath.Join(personalHomePath, "settings.json"), map[string]any{ "type": "personal", "name": personalName, "slug": personalSlug, }); err != nil { return fmt.Errorf("write personal settings.json: %w", err) } if err := writeJSONFile(filepath.Join(personalHomePath, "layout.json"), map[string]any{ "version": 1, "type": "personal-layout", "home": map[string]any{ "defaultProjectSlug": project.Slug, }, }); err != nil { return fmt.Errorf("write personal layout.json: %w", err) } if err := writeJSONFile(filepath.Join(personalHomePath, "home.json"), map[string]any{ "type": "personal-home", "title": personalHomeTitle(personalName), }); err != nil { return fmt.Errorf("write personal home.json: %w", err) } return nil }