112 lines
3.0 KiB
Go

package ds
import (
"context"
"github.com/oklog/ulid/v2"
"github.com/timetracker/backend/internal/domain/entities"
"github.com/timetracker/backend/internal/domain/persistence"
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
"gorm.io/gorm"
)
type UserDatasource struct {
db *gorm.DB
}
func NewUserDatasource(db *gorm.DB) persistence.UserDatasource {
return &UserDatasource{db: db}
}
func (r *UserDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.User, error) {
var userDBO dbo.UserDBO
if err := r.db.WithContext(ctx).First(&userDBO, "id = ?", id).Error; err != nil {
return nil, err
}
user := &entities.User{
EntityBase: entities.EntityBase{
ID: userDBO.ID,
CreatedAt: userDBO.CreatedAt,
UpdatedAt: userDBO.UpdatedAt,
},
Email: userDBO.Email,
Salt: userDBO.Salt,
Role: userDBO.Role,
CompanyID: userDBO.CompanyID,
HourlyRate: userDBO.HourlyRate,
}
return user, nil
}
func (r *UserDatasource) Create(ctx context.Context, user *entities.User, passwordHash string, salt string) error {
old := r.db.WithContext(ctx).First(&dbo.UserDBO{}, "email = ?", user.Email)
if old.Error == nil {
return entities.ErrUserAlreadyExists
}
userDBO := dbo.UserDBO{
ID: user.ID,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
Email: user.Email,
PasswordHash: passwordHash,
Salt: salt,
Role: user.Role,
CompanyID: user.CompanyID,
HourlyRate: user.HourlyRate,
}
return r.db.WithContext(ctx).Create(&userDBO).Error
}
func (r *UserDatasource) Update(ctx context.Context, user *entities.User, passwordHash *string) error {
var existingUser dbo.UserDBO
if err := r.db.WithContext(ctx).First(&existingUser, "id = ?", user.ID).Error; err != nil {
return entities.ErrUserNotFound
}
// Nur relevante Felder aktualisieren
updateData := map[string]interface{}{
"email": user.Email,
"role": user.Role,
"company_id": user.CompanyID,
"hourly_rate": user.HourlyRate,
"updated_at": gorm.Expr("NOW()"), // Optional: Automatisch das Update-Datum setzen
}
if passwordHash != nil {
updateData["password_hash"] = *passwordHash
}
return r.db.WithContext(ctx).Model(&dbo.UserDBO{}).Where("id = ?", user.ID).Updates(updateData).Error
}
func (r *UserDatasource) Delete(ctx context.Context, id ulid.ULID) error {
return r.db.WithContext(ctx).Delete(&dbo.UserDBO{}, "id = ?", id).Error
}
func (r *UserDatasource) GetByEmail(ctx context.Context, email string) (*entities.User, error) {
var userDBO dbo.UserDBO
if err := r.db.WithContext(ctx).Where("email = ?", email).First(&userDBO).Error; err != nil {
return nil, err
}
user := &entities.User{
EntityBase: entities.EntityBase{
ID: userDBO.ID,
CreatedAt: userDBO.CreatedAt,
UpdatedAt: userDBO.UpdatedAt,
},
Email: userDBO.Email,
Salt: userDBO.Salt,
Role: userDBO.Role,
CompanyID: userDBO.CompanyID,
HourlyRate: userDBO.HourlyRate,
}
return user, nil
}