142 lines
4.3 KiB
Go
142 lines
4.3 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
// UserRepo implements GORM repository for User.
|
|
// Reference: Chatwoot app/models/user.rb
|
|
type UserRepo struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewUserRepo creates a new User repository.
|
|
func NewUserRepo(db *gorm.DB) *UserRepo {
|
|
return &UserRepo{db: db}
|
|
}
|
|
|
|
// FindByID retrieves a user by primary key.
|
|
func (r *UserRepo) FindByID(ctx context.Context, id uint) (*model.User, error) {
|
|
var user model.User
|
|
err := r.db.WithContext(ctx).First(&user, id).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &user, nil
|
|
}
|
|
|
|
// FindByIDs retrieves multiple users by their primary keys.
|
|
func (r *UserRepo) FindByIDs(ctx context.Context, ids []uint) ([]model.User, error) {
|
|
if len(ids) == 0 {
|
|
return []model.User{}, nil
|
|
}
|
|
var users []model.User
|
|
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&users).Error
|
|
return users, err
|
|
}
|
|
|
|
// FindByEmail retrieves a user by email address.
|
|
func (r *UserRepo) FindByEmail(ctx context.Context, email string) (*model.User, error) {
|
|
var user model.User
|
|
err := r.db.WithContext(ctx).Where("email = ?", email).First(&user).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &user, nil
|
|
}
|
|
|
|
// Create inserts a new user.
|
|
func (r *UserRepo) Create(ctx context.Context, user *model.User) error {
|
|
return r.db.WithContext(ctx).Create(user).Error
|
|
}
|
|
|
|
// Update modifies an existing user.
|
|
func (r *UserRepo) Update(ctx context.Context, user *model.User) error {
|
|
return r.db.WithContext(ctx).Save(user).Error
|
|
}
|
|
|
|
// Delete soft-deletes a user.
|
|
func (r *UserRepo) Delete(ctx context.Context, id uint) error {
|
|
return r.db.WithContext(ctx).Delete(&model.User{}, id).Error
|
|
}
|
|
|
|
// List retrieves all users with pagination.
|
|
func (r *UserRepo) List(ctx context.Context, offset, limit int) ([]model.User, int64, error) {
|
|
var users []model.User
|
|
var total int64
|
|
|
|
if err := r.db.WithContext(ctx).Model(&model.User{}).Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
err := r.db.WithContext(ctx).Offset(offset).Limit(limit).Order("id ASC").
|
|
Find(&users).Error
|
|
return users, total, err
|
|
}
|
|
|
|
// Search searches users by name or email.
|
|
func (r *UserRepo) Search(ctx context.Context, query string, offset, limit int) ([]model.User, int64, error) {
|
|
var users []model.User
|
|
var total int64
|
|
|
|
likeQuery := "%" + query + "%"
|
|
condition := r.db.WithContext(ctx).Model(&model.User{}).
|
|
Where("name ILIKE ? OR email ILIKE ?", likeQuery, likeQuery)
|
|
|
|
if err := condition.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
err := condition.Offset(offset).Limit(limit).Order("id ASC").
|
|
Find(&users).Error
|
|
return users, total, err
|
|
}
|
|
|
|
// UpdateAvailability updates user availability status.
|
|
// Accepts "online"/"available" → true, anything else → false.
|
|
func (r *UserRepo) UpdateAvailability(ctx context.Context, id uint, availability string) error {
|
|
isAvailable := availability == "online" || availability == "available"
|
|
return r.db.WithContext(ctx).Model(&model.User{}).Where("id = ?", id).
|
|
Update("available", isAvailable).Error
|
|
}
|
|
|
|
// UpdateLastSignIn updates sign-in tracking fields.
|
|
func (r *UserRepo) UpdateLastSignIn(ctx context.Context, id uint, ip string) error {
|
|
return r.db.WithContext(ctx).Model(&model.User{}).Where("id = ?", id).
|
|
Updates(map[string]interface{}{
|
|
"last_sign_in_ip": ip,
|
|
"current_sign_in_ip": ip,
|
|
"sign_in_count": gorm.Expr("sign_in_count + 1"),
|
|
}).Error
|
|
}
|
|
|
|
// FindByAccount retrieves users belonging to an account (delegated to AccountRepo).
|
|
func (r *UserRepo) FindByAccount(ctx context.Context, accountID uint, offset, limit int) ([]model.User, int64, error) {
|
|
var users []model.User
|
|
var total int64
|
|
|
|
countDB := r.db.WithContext(ctx).Model(&model.User{}).
|
|
Joins("JOIN account_users ON account_users.user_id = users.id").
|
|
Where("account_users.account_id = ?", accountID)
|
|
if err := countDB.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
err := r.db.WithContext(ctx).
|
|
Joins("JOIN account_users ON account_users.user_id = users.id").
|
|
Where("account_users.account_id = ?", accountID).
|
|
Offset(offset).Limit(limit).Order("id ASC").
|
|
Find(&users).Error
|
|
return users, total, err
|
|
}
|
|
|
|
// Count returns total number of users.
|
|
func (r *UserRepo) Count(ctx context.Context) (int64, error) {
|
|
var total int64
|
|
err := r.db.WithContext(ctx).Model(&model.User{}).Count(&total).Error
|
|
return total, err
|
|
} |