package repository import ( dbgen "Yimaru-Backend/gen/db" "Yimaru-Backend/internal/domain" "Yimaru-Backend/internal/ports" "Yimaru-Backend/internal/services/authentication" "context" "database/sql" "errors" "time" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" ) func NewUserStore(s *Store) ports.UserStore { return s } func (s *Store) GetUserDeviceTokens(ctx context.Context, userID int64) ([]string, error) { return s.queries.GetActiveDeviceTokens(ctx, userID) } func (s *Store) RegisterDevice(ctx context.Context, userID int64, deviceToken, platform string) error { _, err := s.queries.CreateDevice(ctx, dbgen.CreateDeviceParams{ UserID: userID, DeviceToken: deviceToken, Platform: pgtype.Text{String: platform, Valid: platform != ""}, }) return err } func (s *Store) DeactivateDevice(ctx context.Context, userID int64, deviceToken string) error { return s.queries.DeactivateDeviceByToken(ctx, dbgen.DeactivateDeviceByTokenParams{ UserID: userID, DeviceToken: deviceToken, }) } func (s *Store) DeactivateAllUserDevices(ctx context.Context, userID int64) error { return s.queries.DeactivateUserDevices(ctx, userID) } func (s *Store) LinkGoogleAccount( ctx context.Context, userID int64, googleID string, ) error { return s.queries.LinkGoogleAccount(ctx, dbgen.LinkGoogleAccountParams{ ID: userID, GoogleID: pgtype.Text{String: googleID, Valid: true}, }) } func (s *Store) CreateGoogleUser( ctx context.Context, gUser domain.GoogleUser, ) (domain.User, error) { res, err := s.queries.CreateGoogleUser(ctx, dbgen.CreateGoogleUserParams{ FirstName: pgtype.Text{String: gUser.GivenName, Valid: true}, LastName: pgtype.Text{String: gUser.FamilyName, Valid: true}, Email: pgtype.Text{String: gUser.Email, Valid: true}, GoogleID: pgtype.Text{String: gUser.ID, Valid: true}, GoogleEmailVerified: pgtype.Bool{Bool: gUser.VerifiedEmail, Valid: true}, Role: string(domain.RoleStudent), Status: string(domain.UserStatusActive), ProfilePictureUrl: pgtype.Text{ String: gUser.Picture, Valid: gUser.Picture != "", }, }) if err != nil { return domain.User{}, err } return mapDBUser(res, nil, nil), nil } func (s *Store) GetProfileCompletionStatus(ctx context.Context, userId int64) (ports.ProfileCompletionStatus, error) { result, err := s.queries.GetProfileCompletionStatus(ctx, userId) if err != nil { if errors.Is(err, sql.ErrNoRows) { return ports.ProfileCompletionStatus{}, authentication.ErrUserNotFound } return ports.ProfileCompletionStatus{}, err } return ports.ProfileCompletionStatus{ IsCompleted: result.ProfileCompleted.Bool, Percentage: int(result.ProfileCompletionPercentage), }, nil } func (s *Store) UpdateUserKnowledgeLevel(ctx context.Context, userID int64, knowledgeLevel string) error { return s.queries.UpdateUserKnowledgeLevel(ctx, dbgen.UpdateUserKnowledgeLevelParams{ ID: userID, KnowledgeLevel: pgtype.Text{String: knowledgeLevel, Valid: true}, }) } func (s *Store) IsUserPending(ctx context.Context, userID int64) (bool, error) { isPending, err := s.queries.IsUserPending(ctx, userID) if err != nil { if errors.Is(err, sql.ErrNoRows) { return false, authentication.ErrUserNotFound } return false, err } return isPending, nil } func (s *Store) IsUserNameUnique(ctx context.Context, userID int64) (bool, error) { isUnique, err := s.queries.IsUserNameUnique(ctx, userID) if err != nil { return false, err } return isUnique, nil } func (s *Store) UpdateUserStatus(ctx context.Context, req domain.UpdateUserStatusReq) error { return s.queries.UpdateUserStatus(ctx, dbgen.UpdateUserStatusParams{ Status: req.Status, ID: req.UserID, }) } func (s *Store) CreateUserWithoutOtp( ctx context.Context, user domain.User, ) (domain.User, error) { userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{ FirstName: pgtype.Text{String: user.FirstName}, LastName: pgtype.Text{String: user.LastName}, Gender: pgtype.Text{ String: user.Gender, Valid: user.Gender != "", }, BirthDay: pgtype.Date{ Time: user.BirthDay, Valid: true, }, // UserName: user.UserName, Email: pgtype.Text{String: user.Email, Valid: user.Email != ""}, PhoneNumber: pgtype.Text{String: user.PhoneNumber, Valid: user.PhoneNumber != ""}, Role: string(user.Role), Password: user.Password, AgeGroup: pgtype.Text{String: user.AgeGroup, Valid: user.AgeGroup != ""}, EducationLevel: pgtype.Text{String: user.EducationLevel, Valid: user.EducationLevel != ""}, Country: pgtype.Text{String: user.Country, Valid: user.Country != ""}, Region: pgtype.Text{String: user.Region, Valid: user.Region != ""}, NickName: pgtype.Text{ String: user.NickName, Valid: user.NickName != "", }, Occupation: pgtype.Text{ String: user.Occupation, Valid: user.Occupation != "", }, LearningGoal: pgtype.Text{ String: user.LearningGoal, Valid: user.LearningGoal != "", }, LanguageGoal: pgtype.Text{ String: user.LanguageGoal, Valid: user.LanguageGoal != "", }, LanguageChallange: pgtype.Text{ String: user.LanguageChallange, Valid: user.LanguageChallange != "", }, FavouriteTopic: pgtype.Text{ String: user.FavouriteTopic, Valid: user.FavouriteTopic != "", }, EmailVerified: user.EmailVerified, PhoneVerified: user.PhoneVerified, ProfilePictureUrl: pgtype.Text{ String: user.ProfilePictureURL, Valid: user.ProfilePictureURL != "", }, Status: string(user.Status), ProfileCompleted: pgtype.Bool{ Bool: user.ProfileCompleted, Valid: true, }, PreferredLanguage: pgtype.Text{ String: user.PreferredLanguage, Valid: user.PreferredLanguage != "", }, }) if err != nil { return domain.User{}, err } var updatedAt *time.Time if userRes.UpdatedAt.Valid { updatedAt = &userRes.UpdatedAt.Time } return mapCreateUserResult(userRes, user.Password, updatedAt), nil } // CreateUser inserts a new user into the database func (s *Store) CreateUser( ctx context.Context, user domain.User, usedOtpId int64, ) (domain.User, error) { if usedOtpId > 0 { if err := s.queries.MarkOtpAsUsed(ctx, dbgen.MarkOtpAsUsedParams{ ID: usedOtpId, UsedAt: pgtype.Timestamptz{Time: time.Now(), Valid: true}, }); err != nil { return domain.User{}, err } } userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{ FirstName: pgtype.Text{String: user.FirstName}, LastName: pgtype.Text{String: user.LastName}, Gender: pgtype.Text{ String: user.Gender, Valid: user.Gender != "", }, BirthDay: pgtype.Date{ Time: user.BirthDay, Valid: true, }, // UserName: user.UserName, Email: pgtype.Text{String: user.Email, Valid: user.Email != ""}, PhoneNumber: pgtype.Text{String: user.PhoneNumber, Valid: user.PhoneNumber != ""}, Role: string(user.Role), Password: user.Password, AgeGroup: pgtype.Text{String: user.AgeGroup, Valid: user.AgeGroup != ""}, EducationLevel: pgtype.Text{String: user.EducationLevel, Valid: user.EducationLevel != ""}, Country: pgtype.Text{String: user.Country, Valid: user.Country != ""}, Region: pgtype.Text{String: user.Region, Valid: user.Region != ""}, NickName: pgtype.Text{String: user.NickName, Valid: user.NickName != ""}, Occupation: pgtype.Text{String: user.Occupation, Valid: user.Occupation != ""}, LearningGoal: pgtype.Text{String: user.LearningGoal, Valid: user.LearningGoal != ""}, LanguageGoal: pgtype.Text{String: user.LanguageGoal, Valid: user.LanguageGoal != ""}, LanguageChallange: pgtype.Text{String: user.LanguageChallange, Valid: user.LanguageChallange != ""}, FavouriteTopic: pgtype.Text{String: user.FavouriteTopic, Valid: user.FavouriteTopic != ""}, EmailVerified: user.EmailVerified, PhoneVerified: user.PhoneVerified, ProfilePictureUrl: pgtype.Text{ String: user.ProfilePictureURL, Valid: user.ProfilePictureURL != "", }, Status: string(user.Status), ProfileCompleted: pgtype.Bool{ Bool: user.ProfileCompleted, Valid: true, }, PreferredLanguage: pgtype.Text{ String: user.PreferredLanguage, Valid: user.PreferredLanguage != "", }, }) if err != nil { return domain.User{}, err } var updatedAt *time.Time if userRes.UpdatedAt.Valid { updatedAt = &userRes.UpdatedAt.Time } return mapCreateUserResult(userRes, user.Password, updatedAt), nil } // GetUserByID retrieves a user by ID func (s *Store) GetUserByID( ctx context.Context, id int64, ) (domain.User, error) { u, err := s.queries.GetUserByID(ctx, id) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.User{}, domain.ErrUserNotFound } return domain.User{}, err } var lastLogin *time.Time if u.LastLogin.Valid { lastLogin = &u.LastLogin.Time } var updatedAt *time.Time if u.UpdatedAt.Valid { updatedAt = &u.UpdatedAt.Time } return domain.User{ ID: u.ID, FirstName: u.FirstName.String, LastName: u.LastName.String, Gender: u.Gender.String, BirthDay: u.BirthDay.Time, // UserName: u.UserName, Email: u.Email.String, PhoneNumber: u.PhoneNumber.String, Role: domain.Role(u.Role), AgeGroup: u.AgeGroup.String, EducationLevel: u.EducationLevel.String, Country: u.Country.String, Region: u.Region.String, NickName: u.NickName.String, Occupation: u.Occupation.String, LearningGoal: u.LearningGoal.String, LanguageGoal: u.LanguageGoal.String, LanguageChallange: u.LanguageChallange.String, FavouriteTopic: u.FavouriteTopic.String, EmailVerified: u.EmailVerified, PhoneVerified: u.PhoneVerified, Status: domain.UserStatus(u.Status), LastLogin: lastLogin, ProfileCompleted: u.ProfileCompleted.Bool, ProfileCompletionPercentage: int(u.ProfileCompletionPercentage), ProfilePictureURL: u.ProfilePictureUrl.String, PreferredLanguage: u.PreferredLanguage.String, CreatedAt: u.CreatedAt.Time, UpdatedAt: updatedAt, }, nil } func (s *Store) GetUserByGoogleID( ctx context.Context, googleId string, ) (domain.User, error) { u, err := s.queries.GetUserByGoogleID(ctx, pgtype.Text{String: googleId, Valid: googleId != ""}) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.User{}, domain.ErrUserNotFound } return domain.User{}, err } var lastLogin *time.Time if u.LastLogin.Valid { lastLogin = &u.LastLogin.Time } var updatedAt *time.Time if u.UpdatedAt.Valid { updatedAt = &u.UpdatedAt.Time } return domain.User{ ID: u.ID, FirstName: u.FirstName.String, LastName: u.LastName.String, Gender: u.Gender.String, BirthDay: u.BirthDay.Time, // UserName: u.UserName, Email: u.Email.String, PhoneNumber: u.PhoneNumber.String, Role: domain.Role(u.Role), AgeGroup: u.AgeGroup.String, EducationLevel: u.EducationLevel.String, Country: u.Country.String, Region: u.Region.String, NickName: u.NickName.String, Occupation: u.Occupation.String, LearningGoal: u.LearningGoal.String, LanguageGoal: u.LanguageGoal.String, LanguageChallange: u.LanguageChallange.String, FavouriteTopic: u.FavouriteTopic.String, EmailVerified: u.EmailVerified, PhoneVerified: u.PhoneVerified, Status: domain.UserStatus(u.Status), LastLogin: lastLogin, ProfileCompleted: u.ProfileCompleted.Bool, ProfilePictureURL: u.ProfilePictureUrl.String, PreferredLanguage: u.PreferredLanguage.String, CreatedAt: u.CreatedAt.Time, UpdatedAt: updatedAt, }, nil } // GetAllUsers retrieves users with optional filters func (s *Store) GetAllUsers( ctx context.Context, role *string, status *string, query *string, createdBefore, createdAfter *time.Time, limit, offset int32, ) ([]domain.User, int64, error) { var roleParam pgtype.Text if role != nil && *role != "" { roleParam = pgtype.Text{String: *role, Valid: true} } var statusParam pgtype.Text if status != nil && *status != "" { statusParam = pgtype.Text{String: *status, Valid: true} } var queryParam pgtype.Text if query != nil && *query != "" { queryParam = pgtype.Text{String: *query, Valid: true} } var createdAfterParam pgtype.Timestamptz if createdAfter != nil { createdAfterParam = pgtype.Timestamptz{Time: *createdAfter, Valid: true} } var createdBeforeParam pgtype.Timestamptz if createdBefore != nil { createdBeforeParam = pgtype.Timestamptz{Time: *createdBefore, Valid: true} } params := dbgen.GetAllUsersParams{ Role: roleParam, Status: statusParam, Query: queryParam, CreatedAfter: createdAfterParam, CreatedBefore: createdBeforeParam, Limit: pgtype.Int4{ Int32: limit, Valid: true, }, Offset: pgtype.Int4{ Int32: offset, Valid: true, }, } rows, err := s.queries.GetAllUsers(ctx, params) if err != nil { return nil, 0, err } if len(rows) == 0 { return []domain.User{}, 0, nil } totalCount := rows[0].TotalCount users := make([]domain.User, 0, len(rows)) for _, u := range rows { var updatedAt *time.Time if u.UpdatedAt.Valid { updatedAt = &u.UpdatedAt.Time } users = append(users, domain.User{ ID: u.ID, FirstName: u.FirstName.String, LastName: u.LastName.String, Gender: u.Gender.String, BirthDay: u.BirthDay.Time, // UserName: u.UserName, Email: u.Email.String, PhoneNumber: u.PhoneNumber.String, Role: domain.Role(u.Role), AgeGroup: u.AgeGroup.String, EducationLevel: u.EducationLevel.String, Country: u.Country.String, Region: u.Region.String, NickName: u.NickName.String, Occupation: u.Occupation.String, LearningGoal: u.LearningGoal.String, LanguageGoal: u.LanguageGoal.String, LanguageChallange: u.LanguageChallange.String, FavouriteTopic: u.FavouriteTopic.String, EmailVerified: u.EmailVerified, PhoneVerified: u.PhoneVerified, Status: domain.UserStatus(u.Status), ProfilePictureURL: u.ProfilePictureUrl.String, ProfileCompleted: u.ProfileCompleted.Bool, PreferredLanguage: u.PreferredLanguage.String, CreatedAt: u.CreatedAt.Time, UpdatedAt: updatedAt, }) } return users, totalCount, nil } // GetTotalUsers counts users with optional filters func (s *Store) GetTotalUsers(ctx context.Context, role *string) (int64, error) { count, err := s.queries.GetTotalUsers(ctx, *role) if err != nil { return 0, err } return count, nil } // SearchUserByNameOrPhone searches users by name or phone func (s *Store) SearchUserByNameOrPhone( ctx context.Context, search string, role *string, ) ([]domain.User, error) { params := dbgen.SearchUserByNameOrPhoneParams{ Column1: pgtype.Text{ String: search, Valid: search != "", }, } if role != nil { params.Role = pgtype.Text{ String: *role, Valid: true, } } rows, err := s.queries.SearchUserByNameOrPhone(ctx, params) if err != nil { return nil, err } if len(rows) == 0 { return []domain.User{}, nil } users := make([]domain.User, 0, len(rows)) for _, u := range rows { var updatedAt *time.Time if u.UpdatedAt.Valid { updatedAt = &u.UpdatedAt.Time } users = append(users, domain.User{ ID: u.ID, FirstName: u.FirstName.String, LastName: u.LastName.String, Gender: u.Gender.String, BirthDay: u.BirthDay.Time, // UserName: u.UserName, Email: u.Email.String, PhoneNumber: u.PhoneNumber.String, Role: domain.Role(u.Role), AgeGroup: u.AgeGroup.String, EducationLevel: u.EducationLevel.String, Country: u.Country.String, Region: u.Region.String, NickName: u.NickName.String, Occupation: u.Occupation.String, LearningGoal: u.LearningGoal.String, LanguageGoal: u.LanguageGoal.String, LanguageChallange: u.LanguageChallange.String, FavouriteTopic: u.FavouriteTopic.String, EmailVerified: u.EmailVerified, PhoneVerified: u.PhoneVerified, Status: domain.UserStatus(u.Status), ProfileCompleted: u.ProfileCompleted.Bool, ProfilePictureURL: u.ProfilePictureUrl.String, PreferredLanguage: u.PreferredLanguage.String, CreatedAt: u.CreatedAt.Time, UpdatedAt: updatedAt, }) } return users, nil } // UpdateUser updates basic user info func (s *Store) UpdateUser( ctx context.Context, req domain.UpdateUserReq, ) error { var birthDate pgtype.Date if req.BirthDay != nil && *req.BirthDay != "" { t, err := time.Parse("2006-01-02", *req.BirthDay) if err != nil { return err } birthDate = pgtype.Date{Time: t, Valid: true} } var ageGroup pgtype.Text if req.AgeGroup != nil { ageGroup = pgtype.Text{String: string(*req.AgeGroup), Valid: true} } return s.queries.UpdateUser(ctx, dbgen.UpdateUserParams{ FirstName: pgtype.Text{String: req.FirstName, Valid: req.FirstName != ""}, LastName: pgtype.Text{String: req.LastName, Valid: req.LastName != ""}, KnowledgeLevel: pgtype.Text{String: req.KnowledgeLevel, Valid: req.KnowledgeLevel != ""}, AgeGroup: ageGroup, EducationLevel: pgtype.Text{String: req.EducationLevel, Valid: req.EducationLevel != ""}, Country: pgtype.Text{String: req.Country, Valid: req.Country != ""}, Region: pgtype.Text{String: req.Region, Valid: req.Region != ""}, NickName: pgtype.Text{String: req.NickName, Valid: req.NickName != ""}, Occupation: pgtype.Text{String: req.Occupation, Valid: req.Occupation != ""}, LearningGoal: pgtype.Text{String: req.LearningGoal, Valid: req.LearningGoal != ""}, LanguageGoal: pgtype.Text{String: req.LanguageGoal, Valid: req.LanguageGoal != ""}, LanguageChallange: pgtype.Text{String: req.LanguageChallange, Valid: req.LanguageChallange != ""}, FavouriteTopic: pgtype.Text{String: req.FavouriteTopic, Valid: req.FavouriteTopic != ""}, InitialAssessmentCompleted: req.InitialAssessmentCompleted, ProfilePictureUrl: pgtype.Text{String: req.ProfilePictureURL, Valid: req.ProfilePictureURL != ""}, PreferredLanguage: pgtype.Text{String: req.PreferredLanguage, Valid: req.PreferredLanguage != ""}, Gender: pgtype.Text{String: req.Gender, Valid: req.Gender != ""}, BirthDay: birthDate, ID: req.UserID, }) } // DeleteUser removes a user func (s *Store) DeleteUser(ctx context.Context, userID int64) error { return s.queries.DeleteUser(ctx, userID) } // CheckPhoneEmailExist checks if phone or email exists in an organization func (s *Store) CheckPhoneEmailExist(ctx context.Context, phone, email string) (phoneExists, emailExists bool, err error) { res, err := s.queries.CheckPhoneEmailExist(ctx, dbgen.CheckPhoneEmailExistParams{ PhoneNumber: pgtype.Text{String: phone}, Email: pgtype.Text{String: email}, }) if err != nil { return false, false, err } return res.PhoneExists, res.EmailExists, nil } // GetUserByEmail retrieves a user by email and organization func (s *Store) GetUserByEmailPhone( ctx context.Context, email string, phone string, ) (domain.User, error) { u, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{ Email: pgtype.Text{ String: email, Valid: email != "", }, PhoneNumber: pgtype.Text{ String: phone, Valid: phone != "", }, }) if err != nil { if errors.Is(err, sql.ErrNoRows) || errors.Is(err, pgx.ErrNoRows) { return domain.User{}, domain.ErrUserNotFound } return domain.User{}, err } var lastLogin *time.Time if u.LastLogin.Valid { lastLogin = &u.LastLogin.Time } var updatedAt *time.Time if u.UpdatedAt.Valid { updatedAt = &u.UpdatedAt.Time } return domain.User{ ID: u.ID, FirstName: u.FirstName.String, LastName: u.LastName.String, Gender: u.Gender.String, BirthDay: u.BirthDay.Time, // UserName: u.UserName, Email: u.Email.String, PhoneNumber: u.PhoneNumber.String, Password: u.Password, Role: domain.Role(u.Role), AgeGroup: u.AgeGroup.String, EducationLevel: u.EducationLevel.String, Country: u.Country.String, Region: u.Region.String, NickName: u.NickName.String, Occupation: u.Occupation.String, LearningGoal: u.LearningGoal.String, LanguageGoal: u.LanguageGoal.String, LanguageChallange: u.LanguageChallange.String, FavouriteTopic: u.FavouriteTopic.String, EmailVerified: u.EmailVerified, PhoneVerified: u.PhoneVerified, Status: domain.UserStatus(u.Status), ProfilePictureURL: u.ProfilePictureUrl.String, LastLogin: lastLogin, ProfileCompleted: u.ProfileCompleted.Bool, PreferredLanguage: u.PreferredLanguage.String, CreatedAt: u.CreatedAt.Time, UpdatedAt: updatedAt, }, nil } // UpdatePassword updates a user's password (deprecated - use UpdatePasswordHash) func (s *Store) UpdatePassword(ctx context.Context, password string, userID int64) error { return s.queries.UpdatePassword(ctx, dbgen.UpdatePasswordParams{ Password: []byte(password), ID: userID, }) } // UpdatePasswordHash updates a user's password with a pre-hashed value func (s *Store) UpdatePasswordHash(ctx context.Context, hashedPassword []byte, userID int64) error { return s.queries.UpdatePassword(ctx, dbgen.UpdatePasswordParams{ Password: hashedPassword, ID: userID, }) } // mapUser converts dbgen.User to domain.User func mapCreateUserResult( userRes dbgen.CreateUserRow, password []byte, updatedAt *time.Time, ) domain.User { return domain.User{ ID: userRes.ID, FirstName: userRes.FirstName.String, LastName: userRes.LastName.String, Gender: userRes.Gender.String, BirthDay: userRes.BirthDay.Time, // UserName: userRes.UserName, Email: userRes.Email.String, PhoneNumber: userRes.PhoneNumber.String, Role: domain.Role(userRes.Role), Password: password, AgeGroup: userRes.AgeGroup.String, EducationLevel: userRes.EducationLevel.String, Country: userRes.Country.String, Region: userRes.Region.String, NickName: userRes.NickName.String, Occupation: userRes.Occupation.String, LearningGoal: userRes.LearningGoal.String, LanguageGoal: userRes.LanguageGoal.String, LanguageChallange: userRes.LanguageChallange.String, FavouriteTopic: userRes.FavouriteTopic.String, EmailVerified: userRes.EmailVerified, PhoneVerified: userRes.PhoneVerified, Status: domain.UserStatus(userRes.Status), ProfileCompleted: userRes.ProfileCompleted.Bool, PreferredLanguage: userRes.PreferredLanguage.String, CreatedAt: userRes.CreatedAt.Time, UpdatedAt: updatedAt, } } // mapDBUser converts dbgen.User to domain.User (used by CreateGoogleUser) func mapDBUser( userRes dbgen.User, password []byte, updatedAt *time.Time, ) domain.User { return domain.User{ ID: userRes.ID, FirstName: userRes.FirstName.String, LastName: userRes.LastName.String, Gender: userRes.Gender.String, BirthDay: userRes.BirthDay.Time, // UserName: userRes.UserName, Email: userRes.Email.String, PhoneNumber: userRes.PhoneNumber.String, Role: domain.Role(userRes.Role), Password: password, AgeGroup: userRes.AgeGroup.String, EducationLevel: userRes.EducationLevel.String, Country: userRes.Country.String, Region: userRes.Region.String, NickName: userRes.NickName.String, Occupation: userRes.Occupation.String, LearningGoal: userRes.LearningGoal.String, LanguageGoal: userRes.LanguageGoal.String, LanguageChallange: userRes.LanguageChallange.String, FavouriteTopic: userRes.FavouriteTopic.String, EmailVerified: userRes.EmailVerified, PhoneVerified: userRes.PhoneVerified, Status: domain.UserStatus(userRes.Status), ProfilePictureURL: userRes.ProfilePictureUrl.String, ProfileCompleted: userRes.ProfileCompleted.Bool, PreferredLanguage: userRes.PreferredLanguage.String, CreatedAt: userRes.CreatedAt.Time, UpdatedAt: updatedAt, } }