package user import ( "Yimaru-Backend/internal/domain" "context" "time" ) func (s *Service) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error) { // email,phone,error return s.userStore.CheckPhoneEmailExist(ctx, phoneNum, email) } func (s *Service) SendRegisterCode(ctx context.Context, medium domain.OtpMedium, sentTo string, provider domain.SMSProvider) error { var err error // check if user exists switch medium { case domain.OtpMediumEmail: _, err = s.userStore.GetUserByEmailPhone(ctx, sentTo, "") case domain.OtpMediumSms: _, err = s.userStore.GetUserByEmailPhone(ctx, "", sentTo) } if err != nil && err != domain.ErrUserNotFound { return err } // send otp based on the medium return s.SendOtp(ctx, "", sentTo, domain.OtpRegister, medium, provider) } func (s *Service) RegisterUser(ctx context.Context, registerReq domain.RegisterUserReq) (domain.User, error) { // Check if the email or phone is already registered based on OTP medium phoneExists, emailExists, err := s.userStore.CheckPhoneEmailExist(ctx, registerReq.PhoneNumber, registerReq.Email) if err != nil { return domain.User{}, err } if registerReq.OtpMedium == domain.OtpMediumEmail { if emailExists { return domain.User{}, domain.ErrEmailAlreadyRegistered } } else { if phoneExists { return domain.User{}, domain.ErrPhoneAlreadyRegistered } } // Hash the password hashedPassword, err := hashPassword(registerReq.Password) if err != nil { return domain.User{}, err } // Prepare the user userR := domain.User{ FirstName: registerReq.FirstName, LastName: registerReq.LastName, UserName: registerReq.UserName, Email: registerReq.Email, PhoneNumber: registerReq.PhoneNumber, Password: hashedPassword, Role: domain.RoleStudent, EmailVerified: false, PhoneVerified: false, EducationLevel: registerReq.EducationLevel, Age: registerReq.Age, Country: registerReq.Country, Region: registerReq.Region, Status: domain.UserStatusPending, ProfileCompleted: false, PreferredLanguage: registerReq.PreferredLanguage, // Optional fields NickName: registerReq.NickName, Occupation: registerReq.Occupation, LearningGoal: registerReq.LearningGoal, LanguageGoal: registerReq.LanguageGoal, LanguageChallange: registerReq.LanguageChallange, FavoutiteTopic: registerReq.FavoutiteTopic, // ProfilePictureURL: registerReq.ProfilePictureURL, CreatedAt: time.Now(), } var sentTo string // var provider domain.Provid if registerReq.OtpMedium == domain.OtpMediumEmail { sentTo = registerReq.Email } else { sentTo = registerReq.PhoneNumber } // Send OTP to the user (email/SMS) if err := s.SendOtp(ctx, registerReq.UserName, sentTo, domain.OtpRegister, registerReq.OtpMedium, domain.TwilioSms); err != nil { return domain.User{}, err } // Create the user (no OTP validation yet) user, err := s.userStore.CreateUserWithoutOtp(ctx, userR) if err != nil { return domain.User{}, err } return user, nil }