package db import ( "database/sql" "novamd/internal/models" ) // CreateUser inserts a new user record into the database func (db *DB) CreateUser(user *models.User) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() result, err := tx.Exec(` INSERT INTO users (email, display_name, password_hash, role) VALUES (?, ?, ?, ?)`, user.Email, user.DisplayName, user.PasswordHash, user.Role) if err != nil { return err } userID, err := result.LastInsertId() if err != nil { return err } user.ID = int(userID) // 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 } // Update user's last workspace ID _, err = tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", defaultWorkspace.ID, user.ID) if err != nil { return err } err = tx.Commit() if err != nil { return err } user.LastWorkspaceID = defaultWorkspace.ID return nil } // Helper function to create a workspace in a transaction func (db *DB) createWorkspaceTx(tx *sql.Tx, workspace *models.Workspace) error { 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 } id, err := result.LastInsertId() if err != nil { return err } workspace.ID = int(id) return nil } // GetUserByID retrieves a user by ID func (db *DB) GetUserByID(id int) (*models.User, error) { user := &models.User{} err := db.QueryRow(` SELECT id, email, display_name, password_hash, role, created_at, last_workspace_id FROM users WHERE id = ?`, id). Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash, &user.Role, &user.CreatedAt, &user.LastWorkspaceID) if err != nil { return nil, err } return user, nil } // GetUserByEmail retrieves a user by email func (db *DB) GetUserByEmail(email string) (*models.User, error) { user := &models.User{} err := db.QueryRow(` SELECT id, email, display_name, password_hash, role, created_at, last_workspace_id FROM users WHERE email = ?`, email). Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash, &user.Role, &user.CreatedAt, &user.LastWorkspaceID) if err != nil { return nil, err } return user, nil } // UpdateUser updates a user's information func (db *DB) UpdateUser(user *models.User) error { _, err := db.Exec(` UPDATE users SET email = ?, display_name = ?, password_hash = ?, role = ?, last_workspace_id = ? WHERE id = ?`, user.Email, user.DisplayName, user.PasswordHash, user.Role, user.LastWorkspaceID, user.ID) return err } // UpdateLastWorkspace updates the last workspace the user accessed func (db *DB) UpdateLastWorkspace(userID int, workspaceName string) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() var workspaceID int err = tx.QueryRow("SELECT id FROM workspaces WHERE user_id = ? AND name = ?", userID, workspaceName).Scan(&workspaceID) if err != nil { return err } _, err = tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", workspaceID, userID) if err != nil { return err } return tx.Commit() } // DeleteUser deletes a user and all their workspaces func (db *DB) DeleteUser(id int) error { 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() } // GetLastWorkspaceName returns the name of the last workspace the user accessed func (db *DB) GetLastWorkspaceName(userID int) (string, error) { var workspaceName string err := db.QueryRow(` SELECT w.name FROM workspaces w JOIN users u ON u.last_workspace_id = w.id WHERE u.id = ?`, userID). Scan(&workspaceName) return workspaceName, err }