Files
apocapoc-api/internal/application/queries/login_user.go
T
david 5d92820591 Remove timezone from User model and pass as request parameter
Timezone is now sent from the client on each request that needs it,
instead of storing it in the database. This simplifies the model and
allows timezone to be dynamic (useful for traveling users).

Changes:
- Remove timezone field from User entity
- Remove timezone from user registration
- GET /habits/today now requires ?timezone= query param
- Add migration to drop timezone column from database
- Update related tests
2025-11-29 16:18:04 +01:00

56 lines
1.2 KiB
Go

package queries
import (
"context"
"apocapoc-api/internal/domain/repositories"
"apocapoc-api/internal/domain/services"
"apocapoc-api/internal/shared/errors"
)
type LoginUserQuery struct {
Email string
Password string
}
type LoginUserResult struct {
UserID string
Email string
}
type LoginUserHandler struct {
userRepo repositories.UserRepository
passwordHasher services.PasswordHasher
}
func NewLoginUserHandler(userRepo repositories.UserRepository, passwordHasher services.PasswordHasher) *LoginUserHandler {
return &LoginUserHandler{
userRepo: userRepo,
passwordHasher: passwordHasher,
}
}
func (h *LoginUserHandler) Handle(ctx context.Context, query LoginUserQuery) (*LoginUserResult, error) {
if query.Email == "" || query.Password == "" {
return nil, errors.ErrInvalidInput
}
user, err := h.userRepo.FindByEmail(ctx, query.Email)
if err != nil {
return nil, errors.ErrNotFound
}
if err := h.passwordHasher.Compare(user.PasswordHash, query.Password); err != nil {
return nil, errors.ErrNotFound
}
if !user.EmailVerified {
return nil, errors.ErrEmailNotVerified
}
return &LoginUserResult{
UserID: user.ID,
Email: user.Email,
}, nil
}