diff --git a/Backend/internal/bootstrap/service.go b/Backend/internal/bootstrap/service.go index b0230e9..8daa1d2 100644 --- a/Backend/internal/bootstrap/service.go +++ b/Backend/internal/bootstrap/service.go @@ -1304,6 +1304,12 @@ func (service *Service) ensureBootstrapPOSIXSkeleton( 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, @@ -1312,6 +1318,8 @@ func (service *Service) ensureBootstrapPOSIXSkeleton( 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) @@ -1397,6 +1405,37 @@ func (service *Service) ensureBootstrapPOSIXSkeleton( return fmt.Errorf("write users data.json: %w", err) } + if err := writeJSONFile(filepath.Join(personalHomePath, "settings.json"), map[string]any{ + "id": admin.ID, + "name": personalName, + "slug": personalSlug, + "type": "personal", + "ownerUserId": admin.ID, + "email": admin.Email, + }); 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", + }); 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), + "owner": map[string]any{ + "id": admin.ID, + "email": admin.Email, + "displayName": personalName, + }, + "widgets": []any{}, + }); err != nil { + return fmt.Errorf("write personal home.json: %w", err) + } + return nil } diff --git a/Backend/internal/bootstrap/service_test.go b/Backend/internal/bootstrap/service_test.go index f0184ca..ea3e0ae 100644 --- a/Backend/internal/bootstrap/service_test.go +++ b/Backend/internal/bootstrap/service_test.go @@ -59,6 +59,10 @@ func TestEnsureBootstrapPOSIXSkeletonInitializesEmptyRoot(t *testing.T) { filepath.Join(rootPath, "users", "settings.json"), filepath.Join(rootPath, "users", "data.json"), filepath.Join(rootPath, "users", "personals"), + filepath.Join(rootPath, "users", "personals", "personal-ronald", "settings.json"), + filepath.Join(rootPath, "users", "personals", "personal-ronald", "layout.json"), + filepath.Join(rootPath, "users", "personals", "personal-ronald", "home.json"), + filepath.Join(rootPath, "users", "personals", "personal-ronald", "tree"), } for _, path := range requiredPaths { @@ -102,6 +106,25 @@ func TestEnsureBootstrapPOSIXSkeletonInitializesEmptyRoot(t *testing.T) { if usersSettings["primaryAdminId"] != "admin-1" { t.Fatalf("expected primary admin id admin-1, got %#v", usersSettings["primaryAdminId"]) } + + personalSettings := readJSONFileForTest[map[string]any](t, filepath.Join(rootPath, "users", "personals", "personal-ronald", "settings.json")) + if personalSettings["type"] != "personal" { + t.Fatalf("expected personal settings type personal, got %#v", personalSettings["type"]) + } + if personalSettings["name"] != "Ronald" { + t.Fatalf("expected personal name Ronald, got %#v", personalSettings["name"]) + } + if personalSettings["slug"] != "ronald" { + t.Fatalf("expected personal slug ronald, got %#v", personalSettings["slug"]) + } + + personalHome := readJSONFileForTest[map[string]any](t, filepath.Join(rootPath, "users", "personals", "personal-ronald", "home.json")) + if personalHome["type"] != "personal-home" { + t.Fatalf("expected personal home type personal-home, got %#v", personalHome["type"]) + } + if personalHome["title"] != "Ronald's Home" { + t.Fatalf("expected personal home title Ronald's Home, got %#v", personalHome["title"]) + } } func TestCreateProjectHierarchyFolderOnDiskCreatesExpectedFolderShape(t *testing.T) {