4c8f3022f0
- Create PasswordHasher interface in domain layer - Implement BcryptHasher in infrastructure layer - Update RegisterUserHandler and LoginUserHandler to use interface - Remove bcrypt dependency from application layer - Update main.go and integration tests with dependency injection - Enhance CI/CD workflow with test and lint jobs - Add code coverage check (minimum 50%) - Add go vet and gofmt validation - Configure build job to depend on test and lint passing - Update GitHub Actions to latest versions (v4→v5) This achieves 100% SOLID compliance (DIP) and ensures Clean Architecture by removing external library dependencies from application/domain layers.
62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
|
|
"apocapoc-api/internal/domain/entities"
|
|
"apocapoc-api/internal/domain/repositories"
|
|
"apocapoc-api/internal/domain/services"
|
|
"apocapoc-api/internal/shared/errors"
|
|
)
|
|
|
|
type RegisterUserCommand struct {
|
|
Email string
|
|
Password string
|
|
Timezone string
|
|
}
|
|
|
|
type RegisterUserHandler struct {
|
|
userRepo repositories.UserRepository
|
|
passwordHasher services.PasswordHasher
|
|
}
|
|
|
|
func NewRegisterUserHandler(userRepo repositories.UserRepository, passwordHasher services.PasswordHasher) *RegisterUserHandler {
|
|
return &RegisterUserHandler{
|
|
userRepo: userRepo,
|
|
passwordHasher: passwordHasher,
|
|
}
|
|
}
|
|
|
|
func (h *RegisterUserHandler) Handle(ctx context.Context, cmd RegisterUserCommand) (string, error) {
|
|
if cmd.Email == "" || cmd.Password == "" {
|
|
return "", errors.ErrInvalidInput
|
|
}
|
|
|
|
if len(cmd.Password) < 8 {
|
|
return "", errors.ErrInvalidInput
|
|
}
|
|
|
|
existing, _ := h.userRepo.FindByEmail(ctx, cmd.Email)
|
|
if existing != nil {
|
|
return "", errors.ErrAlreadyExists
|
|
}
|
|
|
|
hashedPassword, err := h.passwordHasher.Hash(cmd.Password)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
timezone := cmd.Timezone
|
|
if timezone == "" {
|
|
timezone = "UTC"
|
|
}
|
|
|
|
user := entities.NewUser(cmd.Email, hashedPassword, timezone)
|
|
|
|
if err := h.userRepo.Create(ctx, user); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return user.ID, nil
|
|
}
|