package models import ( "errors" "strings" "time" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) // User represents a system user type User struct { gorm.Model FirstName string `json:"first_name" gorm:"not null;size:100" validate:"required,min=2,max=100"` LastName string `json:"last_name" gorm:"not null;size:100" validate:"required,min=2,max=100"` Email string `json:"email" gorm:"unique;not null;size:255" validate:"required,email"` Phone string `json:"phone" gorm:"size:20" validate:"omitempty,min=10,max=20"` Location string `json:"location" gorm:"size:255" validate:"omitempty,max=255"` DateOfBirth time.Time `json:"date_of_birth" validate:"omitempty"` PasswordHash string `json:"-" gorm:"not null;size:255"` IsAdmin bool `json:"is_admin" gorm:"default:false"` Bookings []Booking `json:"bookings" gorm:"foreignKey:UserID"` } // HashPassword hashes the user's password using bcrypt func (u *User) HashPassword(password string) error { if len(password) < 8 { return errors.New("password must be at least 8 characters long") } hashedBytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } u.PasswordHash = string(hashedBytes) return nil } // CheckPassword verifies if the provided password matches the user's hashed password func (u *User) CheckPassword(password string) bool { err := bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password)) return err == nil } // BeforeCreate is a GORM hook that runs before creating a user record func (u *User) BeforeCreate(tx *gorm.DB) error { // Ensure email is lowercase for consistency u.Email = strings.ToLower(u.Email) return nil }