diff --git a/backend/internal/api/routes.go b/backend/internal/api/routes.go index fcf25cd..af0b1f0 100644 --- a/backend/internal/api/routes.go +++ b/backend/internal/api/routes.go @@ -22,7 +22,7 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem) { r.Route("/{workspaceId}", func(r chi.Router) { r.Get("/", GetWorkspace(db)) - r.Put("/", UpdateWorkspace(db)) + r.Put("/", UpdateWorkspace(db, fs)) r.Delete("/", DeleteWorkspace(db)) // File routes @@ -38,12 +38,6 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem) { }) - // Settings routes - r.Route("/settings", func(r chi.Router) { - r.Get("/", GetWorkspaceSettings(db)) - r.Put("/", UpdateWorkspaceSettings(db, fs)) - }) - // Git routes r.Route("/git", func(r chi.Router) { r.Post("/commit", StageCommitAndPush(fs)) diff --git a/backend/internal/api/workspace_handlers.go b/backend/internal/api/workspace_handlers.go index 38e3125..0d1ad0f 100644 --- a/backend/internal/api/workspace_handlers.go +++ b/backend/internal/api/workspace_handlers.go @@ -35,41 +35,18 @@ func CreateWorkspace(db *db.DB) http.HandlerFunc { return } - var requestBody struct { - Name string `json:"name"` - } - - if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil { + var workspace models.Workspace + if err := json.NewDecoder(r.Body).Decode(&workspace); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } - workspace := &models.Workspace{ - UserID: userID, - Name: requestBody.Name, - } - - if err := db.CreateWorkspace(workspace); err != nil { + workspace.UserID = userID + if err := db.CreateWorkspace(&workspace); err != nil { http.Error(w, "Failed to create workspace", http.StatusInternalServerError) return } - defaultSettings := &models.WorkspaceSettings{ - WorkspaceID: workspace.ID, - Settings: models.UserSettings{ - Theme: "light", - AutoSave: false, - GitEnabled: false, - GitAutoCommit: false, - GitCommitMsgTemplate: "${action} ${filename}", - }, - } - - if err := db.SaveWorkspaceSettings(defaultSettings); err != nil { - http.Error(w, "Failed to initialize workspace settings", http.StatusInternalServerError) - return - } - respondJSON(w, workspace) } } @@ -97,7 +74,7 @@ func GetWorkspace(db *db.DB) http.HandlerFunc { } } -func UpdateWorkspace(db *db.DB) http.HandlerFunc { +func UpdateWorkspace(db *db.DB, fs *filesystem.FileSystem) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, workspaceID, err := getUserAndWorkspaceIDs(r) if err != nil { @@ -105,33 +82,56 @@ func UpdateWorkspace(db *db.DB) http.HandlerFunc { return } - var requestBody struct { - Name string `json:"name"` - } - - if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil { + var workspace models.Workspace + if err := json.NewDecoder(r.Body).Decode(&workspace); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } - workspace, err := db.GetWorkspaceByID(workspaceID) + // Set IDs from the request + workspace.ID = workspaceID + workspace.UserID = userID + + // Validate the workspace + if err := workspace.Validate(); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // Get current workspace for comparison + currentWorkspace, err := db.GetWorkspaceByID(workspaceID) if err != nil { http.Error(w, "Workspace not found", http.StatusNotFound) return } - if workspace.UserID != userID { + if currentWorkspace.UserID != userID { http.Error(w, "Unauthorized access to workspace", http.StatusForbidden) return } - workspace.Name = requestBody.Name - if err := db.UpdateWorkspace(workspace); err != nil { + // Handle Git repository setup/teardown if Git settings changed + if workspace.GitEnabled != currentWorkspace.GitEnabled || + (workspace.GitEnabled && (workspace.GitURL != currentWorkspace.GitURL || + workspace.GitUser != currentWorkspace.GitUser || + workspace.GitToken != currentWorkspace.GitToken)) { + if workspace.GitEnabled { + err = fs.SetupGitRepo(userID, workspaceID, workspace.GitURL, workspace.GitUser, workspace.GitToken) + if err != nil { + http.Error(w, "Failed to setup git repo: "+err.Error(), http.StatusInternalServerError) + return + } + } else { + fs.DisableGitRepo(userID, workspaceID) + } + } + + if err := db.UpdateWorkspace(&workspace); err != nil { http.Error(w, "Failed to update workspace", http.StatusInternalServerError) return } - respondJSON(w, map[string]string{"name": workspace.Name}) + respondJSON(w, workspace) } } @@ -207,64 +207,3 @@ func UpdateLastWorkspace(db *db.DB) http.HandlerFunc { respondJSON(w, map[string]string{"message": "Last workspace updated successfully"}) } } - -func GetWorkspaceSettings(db *db.DB) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - _, workspaceID, err := getUserAndWorkspaceIDs(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - settings, err := db.GetWorkspaceSettings(workspaceID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - respondJSON(w, settings) - } -} - -func UpdateWorkspaceSettings(db *db.DB, fs *filesystem.FileSystem) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - userID, workspaceID, err := getUserAndWorkspaceIDs(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - var userSettings models.UserSettings - if err := json.NewDecoder(r.Body).Decode(&userSettings); err != nil { - http.Error(w, "Invalid request body", http.StatusBadRequest) - return - } - - if err := userSettings.Validate(); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - workspaceSettings := &models.WorkspaceSettings{ - WorkspaceID: workspaceID, - Settings: userSettings, - } - - if err := db.SaveWorkspaceSettings(workspaceSettings); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - if userSettings.GitEnabled { - err := fs.SetupGitRepo(userID, workspaceID, userSettings.GitURL, userSettings.GitUser, userSettings.GitToken) - if err != nil { - http.Error(w, "Failed to setup git repo", http.StatusInternalServerError) - return - } - } else { - fs.DisableGitRepo(userID, workspaceID) - } - - respondJSON(w, workspaceSettings) - } -} diff --git a/backend/internal/db/migrations.go b/backend/internal/db/migrations.go index c6d234f..4eb9402 100644 --- a/backend/internal/db/migrations.go +++ b/backend/internal/db/migrations.go @@ -26,21 +26,23 @@ var migrations = []Migration{ last_opened_file_path TEXT ); - -- Create workspaces table + -- Create workspaces table with integrated settings CREATE TABLE IF NOT EXISTS workspaces ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, name TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + -- Settings fields + theme TEXT NOT NULL DEFAULT 'light' CHECK(theme IN ('light', 'dark')), + auto_save BOOLEAN NOT NULL DEFAULT 0, + git_enabled BOOLEAN NOT NULL DEFAULT 0, + git_url TEXT, + git_user TEXT, + git_token TEXT, + git_auto_commit BOOLEAN NOT NULL DEFAULT 0, + git_commit_msg_template TEXT DEFAULT '${action} ${filename}', FOREIGN KEY (user_id) REFERENCES users (id) ); - - -- Create workspace_settings table - CREATE TABLE IF NOT EXISTS workspace_settings ( - workspace_id INTEGER PRIMARY KEY, - settings JSON NOT NULL, - FOREIGN KEY (workspace_id) REFERENCES workspaces (id) - ); `, }, } diff --git a/backend/internal/db/settings.go b/backend/internal/db/settings.go deleted file mode 100644 index 00820b6..0000000 --- a/backend/internal/db/settings.go +++ /dev/null @@ -1,43 +0,0 @@ -package db - -import ( - "database/sql" - "encoding/json" - - "novamd/internal/models" -) - -func (db *DB) GetWorkspaceSettings(workspaceID int) (*models.WorkspaceSettings, error) { - var settings models.WorkspaceSettings - var settingsJSON []byte - - err := db.QueryRow("SELECT workspace_id, settings FROM workspace_settings WHERE workspace_id = ?", workspaceID). - Scan(&settings.WorkspaceID, &settingsJSON) - if err != nil { - if err == sql.ErrNoRows { - // If no settings found, return default settings - settings.WorkspaceID = workspaceID - settings.Settings = models.UserSettings{} // This will be filled with defaults later - return &settings, nil - } - return nil, err - } - - err = json.Unmarshal(settingsJSON, &settings.Settings) - if err != nil { - return nil, err - } - - return &settings, nil -} - -func (db *DB) SaveWorkspaceSettings(settings *models.WorkspaceSettings) error { - settingsJSON, err := json.Marshal(settings.Settings) - if err != nil { - return err - } - - _, err = db.Exec("INSERT OR REPLACE INTO workspace_settings (workspace_id, settings) VALUES (?, ?)", - settings.WorkspaceID, settingsJSON) - return err -} \ No newline at end of file diff --git a/backend/internal/db/user.go b/backend/internal/db/users.go similarity index 63% rename from backend/internal/db/user.go rename to backend/internal/db/users.go index 1e388dc..4a0251d 100644 --- a/backend/internal/db/user.go +++ b/backend/internal/db/users.go @@ -26,11 +26,14 @@ func (db *DB) CreateUser(user *models.User) error { } user.ID = int(userID) - // Create default workspace + // Create default workspace with default settings defaultWorkspace := &models.Workspace{ UserID: user.ID, Name: "Main", } + defaultWorkspace.GetDefaultSettings() // Initialize default settings + + // Create workspace with settings err = db.createWorkspaceTx(tx, defaultWorkspace) if err != nil { return err @@ -52,8 +55,18 @@ func (db *DB) CreateUser(user *models.User) error { } func (db *DB) createWorkspaceTx(tx *sql.Tx, workspace *models.Workspace) error { - result, err := tx.Exec("INSERT INTO workspaces (user_id, name) VALUES (?, ?)", - workspace.UserID, workspace.Name) + result, err := tx.Exec(` + INSERT INTO workspaces ( + user_id, name, + theme, auto_save, + git_enabled, git_url, git_user, git_token, + git_auto_commit, git_commit_msg_template + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + workspace.UserID, workspace.Name, + workspace.Theme, workspace.AutoSave, + workspace.GitEnabled, workspace.GitURL, workspace.GitUser, workspace.GitToken, + workspace.GitAutoCommit, workspace.GitCommitMsgTemplate, + ) if err != nil { return err } @@ -68,10 +81,15 @@ func (db *DB) createWorkspaceTx(tx *sql.Tx, workspace *models.Workspace) error { func (db *DB) GetUserByID(id int) (*models.User, error) { user := &models.User{} err := db.QueryRow(` - SELECT id, email, display_name, role, created_at, last_workspace_id, last_opened_file_path - FROM users WHERE id = ?`, id). + SELECT + u.id, u.email, u.display_name, u.role, u.created_at, + u.last_workspace_id, u.last_opened_file_path, + COALESCE(w.id, 0) as workspace_id + FROM users u + LEFT JOIN workspaces w ON w.id = u.last_workspace_id + WHERE u.id = ?`, id). Scan(&user.ID, &user.Email, &user.DisplayName, &user.Role, &user.CreatedAt, - &user.LastWorkspaceID, &user.LastOpenedFilePath) + &user.LastWorkspaceID, &user.LastOpenedFilePath, &user.LastWorkspaceID) if err != nil { return nil, err } @@ -82,10 +100,15 @@ func (db *DB) GetUserByEmail(email string) (*models.User, error) { user := &models.User{} var lastOpenedFilePath sql.NullString err := db.QueryRow(` - SELECT id, email, display_name, password_hash, role, created_at, last_workspace_id, last_opened_file_path - FROM users WHERE email = ?`, email). + SELECT + u.id, u.email, u.display_name, u.password_hash, u.role, u.created_at, + u.last_workspace_id, u.last_opened_file_path, + COALESCE(w.id, 0) as workspace_id + FROM users u + LEFT JOIN workspaces w ON w.id = u.last_workspace_id + WHERE u.email = ?`, email). Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash, &user.Role, &user.CreatedAt, - &user.LastWorkspaceID, &lastOpenedFilePath) + &user.LastWorkspaceID, &lastOpenedFilePath, &user.LastWorkspaceID) if err != nil { return nil, err } @@ -117,8 +140,25 @@ func (db *DB) UpdateLastOpenedFile(userID int, filePath string) error { } func (db *DB) DeleteUser(id int) error { - _, err := db.Exec("DELETE FROM users WHERE id = ?", id) - return err + tx, err := db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + // Delete all user's workspaces first + _, err = tx.Exec("DELETE FROM workspaces WHERE user_id = ?", id) + if err != nil { + return err + } + + // Delete the user + _, err = tx.Exec("DELETE FROM users WHERE id = ?", id) + if err != nil { + return err + } + + return tx.Commit() } func (db *DB) GetLastWorkspaceID(userID int) (int, error) { diff --git a/backend/internal/db/workspace.go b/backend/internal/db/workspace.go deleted file mode 100644 index 9d02cae..0000000 --- a/backend/internal/db/workspace.go +++ /dev/null @@ -1,59 +0,0 @@ -package db - -import ( - "novamd/internal/models" -) - -func (db *DB) CreateWorkspace(workspace *models.Workspace) error { - result, err := db.Exec("INSERT INTO workspaces (user_id, name) VALUES (?, ?)", - workspace.UserID, workspace.Name) - if err != nil { - return err - } - id, err := result.LastInsertId() - if err != nil { - return err - } - workspace.ID = int(id) - return nil -} - -func (db *DB) GetWorkspaceByID(id int) (*models.Workspace, error) { - workspace := &models.Workspace{} - err := db.QueryRow("SELECT id, user_id, name, created_at FROM workspaces WHERE id = ?", id). - Scan(&workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt) - if err != nil { - return nil, err - } - return workspace, nil -} - -func (db *DB) GetWorkspacesByUserID(userID int) ([]*models.Workspace, error) { - rows, err := db.Query("SELECT id, user_id, name, created_at FROM workspaces WHERE user_id = ?", userID) - if err != nil { - return nil, err - } - defer rows.Close() - - var workspaces []*models.Workspace - for rows.Next() { - workspace := &models.Workspace{} - err := rows.Scan(&workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt) - if err != nil { - return nil, err - } - workspaces = append(workspaces, workspace) - } - return workspaces, nil -} - -func (db *DB) UpdateWorkspace(workspace *models.Workspace) error { - _, err := db.Exec("UPDATE workspaces SET name = ? WHERE id = ? AND user_id = ?", - workspace.Name, workspace.ID, workspace.UserID) - return err -} - -func (db *DB) DeleteWorkspace(id int) error { - _, err := db.Exec("DELETE FROM workspaces WHERE id = ?", id) - return err -} diff --git a/backend/internal/db/workspaces.go b/backend/internal/db/workspaces.go new file mode 100644 index 0000000..7fb2038 --- /dev/null +++ b/backend/internal/db/workspaces.go @@ -0,0 +1,151 @@ +package db + +import ( + "novamd/internal/models" +) + +func (db *DB) CreateWorkspace(workspace *models.Workspace) error { + // Set default settings if not provided + if workspace.Theme == "" { + workspace.GetDefaultSettings() + } + + result, err := db.Exec(` + INSERT INTO workspaces ( + user_id, name, theme, auto_save, + git_enabled, git_url, git_user, git_token, + git_auto_commit, git_commit_msg_template + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + workspace.UserID, workspace.Name, workspace.Theme, workspace.AutoSave, + workspace.GitEnabled, workspace.GitURL, workspace.GitUser, workspace.GitToken, + workspace.GitAutoCommit, workspace.GitCommitMsgTemplate, + ) + if err != nil { + return err + } + + id, err := result.LastInsertId() + if err != nil { + return err + } + workspace.ID = int(id) + return nil +} + +func (db *DB) GetWorkspaceByID(id int) (*models.Workspace, error) { + workspace := &models.Workspace{} + err := db.QueryRow(` + SELECT + id, user_id, name, created_at, + theme, auto_save, + git_enabled, git_url, git_user, git_token, + git_auto_commit, git_commit_msg_template + FROM workspaces + WHERE id = ?`, + id, + ).Scan( + &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, + &workspace.Theme, &workspace.AutoSave, + &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &workspace.GitToken, + &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, + ) + if err != nil { + return nil, err + } + return workspace, nil +} + +func (db *DB) GetWorkspacesByUserID(userID int) ([]*models.Workspace, error) { + rows, err := db.Query(` + SELECT + id, user_id, name, created_at, + theme, auto_save, + git_enabled, git_url, git_user, git_token, + git_auto_commit, git_commit_msg_template + FROM workspaces + WHERE user_id = ?`, + userID, + ) + if err != nil { + return nil, err + } + defer rows.Close() + + var workspaces []*models.Workspace + for rows.Next() { + workspace := &models.Workspace{} + err := rows.Scan( + &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, + &workspace.Theme, &workspace.AutoSave, + &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &workspace.GitToken, + &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, + ) + if err != nil { + return nil, err + } + workspaces = append(workspaces, workspace) + } + return workspaces, nil +} + +func (db *DB) UpdateWorkspace(workspace *models.Workspace) error { + _, err := db.Exec(` + UPDATE workspaces + SET + name = ?, + theme = ?, + auto_save = ?, + git_enabled = ?, + git_url = ?, + git_user = ?, + git_token = ?, + git_auto_commit = ?, + git_commit_msg_template = ? + WHERE id = ? AND user_id = ?`, + workspace.Name, + workspace.Theme, + workspace.AutoSave, + workspace.GitEnabled, + workspace.GitURL, + workspace.GitUser, + workspace.GitToken, + workspace.GitAutoCommit, + workspace.GitCommitMsgTemplate, + workspace.ID, + workspace.UserID, + ) + return err +} + +// UpdateWorkspaceSettings updates only the settings portion of a workspace +// This is useful when you don't want to modify the name or other core workspace properties +func (db *DB) UpdateWorkspaceSettings(workspace *models.Workspace) error { + _, err := db.Exec(` + UPDATE workspaces + SET + theme = ?, + auto_save = ?, + git_enabled = ?, + git_url = ?, + git_user = ?, + git_token = ?, + git_auto_commit = ?, + git_commit_msg_template = ? + WHERE id = ?`, + workspace.Theme, + workspace.AutoSave, + workspace.GitEnabled, + workspace.GitURL, + workspace.GitUser, + workspace.GitToken, + workspace.GitAutoCommit, + workspace.GitCommitMsgTemplate, + workspace.ID, + ) + return err +} + +func (db *DB) DeleteWorkspace(id int) error { + _, err := db.Exec("DELETE FROM workspaces WHERE id = ?", id) + return err +} diff --git a/backend/internal/models/settings.go b/backend/internal/models/settings.go deleted file mode 100644 index 52a15cb..0000000 --- a/backend/internal/models/settings.go +++ /dev/null @@ -1,46 +0,0 @@ -package models - -import ( - "encoding/json" - - "github.com/go-playground/validator/v10" -) - -type UserSettings struct { - Theme string `json:"theme" validate:"oneof=light dark"` - AutoSave bool `json:"autoSave"` - GitEnabled bool `json:"gitEnabled"` - GitURL string `json:"gitUrl" validate:"required_with=GitEnabled"` - GitUser string `json:"gitUser" validate:"required_with=GitEnabled"` - GitToken string `json:"gitToken" validate:"required_with=GitEnabled"` - GitAutoCommit bool `json:"gitAutoCommit"` - GitCommitMsgTemplate string `json:"gitCommitMsgTemplate"` -} - -type WorkspaceSettings struct { - WorkspaceID int `json:"workspaceId" validate:"required,min=1"` - Settings UserSettings `json:"settings" validate:"required"` -} - -var validate = validator.New() - -func (s *UserSettings) Validate() error { - return validate.Struct(s) -} - -func (ws *WorkspaceSettings) Validate() error { - return validate.Struct(ws) -} - -func (ws *WorkspaceSettings) UnmarshalJSON(data []byte) error { - type Alias WorkspaceSettings - aux := &struct { - *Alias - }{ - Alias: (*Alias)(ws), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - return ws.Validate() -} \ No newline at end of file diff --git a/backend/internal/models/user.go b/backend/internal/models/user.go index ff8e599..8881601 100644 --- a/backend/internal/models/user.go +++ b/backend/internal/models/user.go @@ -2,8 +2,12 @@ package models import ( "time" + + "github.com/go-playground/validator/v10" ) +var validate = validator.New() + type UserRole string const ( diff --git a/backend/internal/models/workspace.go b/backend/internal/models/workspace.go index ced4816..28f1bc5 100644 --- a/backend/internal/models/workspace.go +++ b/backend/internal/models/workspace.go @@ -9,8 +9,29 @@ type Workspace struct { UserID int `json:"userId" validate:"required,min=1"` Name string `json:"name" validate:"required"` CreatedAt time.Time `json:"createdAt"` + + // Integrated settings + Theme string `json:"theme" validate:"oneof=light dark"` + AutoSave bool `json:"autoSave"` + GitEnabled bool `json:"gitEnabled"` + GitURL string `json:"gitUrl" validate:"required_if=GitEnabled true"` + GitUser string `json:"gitUser" validate:"required_if=GitEnabled true"` + GitToken string `json:"gitToken" validate:"required_if=GitEnabled true"` + GitAutoCommit bool `json:"gitAutoCommit"` + GitCommitMsgTemplate string `json:"gitCommitMsgTemplate"` } func (w *Workspace) Validate() error { return validate.Struct(w) } + +func (w *Workspace) GetDefaultSettings() { + w.Theme = "light" + w.AutoSave = false + w.GitEnabled = false + w.GitURL = "" + w.GitUser = "" + w.GitToken = "" + w.GitAutoCommit = false + w.GitCommitMsgTemplate = "${action} ${filename}" +} diff --git a/backend/internal/user/user.go b/backend/internal/user/user.go index ed7d8e5..b725256 100644 --- a/backend/internal/user/user.go +++ b/backend/internal/user/user.go @@ -17,17 +17,6 @@ type UserService struct { FS *filesystem.FileSystem } -// Default settings for new workspaces -var defaultWorkspaceSettings = models.WorkspaceSettings{ - Settings: models.UserSettings{ - Theme: "light", - AutoSave: false, - GitEnabled: false, - GitAutoCommit: false, - GitCommitMsgTemplate: "${action} ${filename}", - }, -} - func NewUserService(database *db.DB, fs *filesystem.FileSystem) *UserService { return &UserService{ DB: database, @@ -68,18 +57,12 @@ func (s *UserService) SetupAdminUser() (*models.User, error) { return nil, fmt.Errorf("failed to create admin user: %w", err) } + // Initialize workspace directory err = s.FS.InitializeUserWorkspace(adminUser.ID, adminUser.LastWorkspaceID) if err != nil { return nil, fmt.Errorf("failed to initialize admin workspace: %w", err) } - // Save default settings for the admin workspace - defaultWorkspaceSettings.WorkspaceID = adminUser.LastWorkspaceID - err = s.DB.SaveWorkspaceSettings(&defaultWorkspaceSettings) - if err != nil { - return nil, fmt.Errorf("failed to save default workspace settings: %w", err) - } - log.Printf("Created admin user with ID: %d and default workspace with ID: %d", adminUser.ID, adminUser.LastWorkspaceID) return adminUser, nil @@ -96,14 +79,6 @@ func (s *UserService) CreateUser(user *models.User) error { return fmt.Errorf("failed to initialize user workspace: %w", err) } - // Save default settings for the user's workspace - settings := defaultWorkspaceSettings - settings.WorkspaceID = user.LastWorkspaceID - err = s.DB.SaveWorkspaceSettings(&settings) - if err != nil { - return fmt.Errorf("failed to save default workspace settings: %w", err) - } - return nil } @@ -120,29 +95,26 @@ func (s *UserService) UpdateUser(user *models.User) error { } func (s *UserService) DeleteUser(id int) error { - // First, get the user to check if they exist and to get their workspaces + // First, get the user to check if they exist user, err := s.DB.GetUserByID(id) if err != nil { return fmt.Errorf("failed to get user: %w", err) } - // Delete user's workspaces + // Get user's workspaces workspaces, err := s.DB.GetWorkspacesByUserID(id) if err != nil { return fmt.Errorf("failed to get user's workspaces: %w", err) } + // Delete workspace directories for _, workspace := range workspaces { - err = s.DB.DeleteWorkspace(workspace.ID) - if err != nil { - return fmt.Errorf("failed to delete workspace: %w", err) - } err = s.FS.DeleteUserWorkspace(user.ID, workspace.ID) if err != nil { return fmt.Errorf("failed to delete workspace files: %w", err) } } - // Finally, delete the user + // Delete user from database (this will cascade delete workspaces) return s.DB.DeleteUser(id) }