data seed and authorization fixes

This commit is contained in:
Yared Yemane 2026-01-14 02:27:26 -08:00
parent 87e57ca548
commit 513927f48f
23 changed files with 787 additions and 831 deletions

View File

@ -5,7 +5,7 @@ INSERT INTO users (
id,
first_name,
last_name,
user_name,
-- user_name,
email,
phone_number,
role,
@ -22,7 +22,7 @@ VALUES
10,
'Demo',
'Student',
'demo_student',
-- 'demo_student',
'student10@yimaru.com',
NULL,
'USER',
@ -38,7 +38,7 @@ VALUES
11,
'System',
'Admin',
'sys_admin',
-- 'sys_admin',
'admin@yimaru.com',
'0911001100',
'ADMIN',
@ -54,7 +54,7 @@ VALUES
12,
'Support',
'Agent',
'support_agent',
-- 'support_agent',
'support@yimaru.com',
'0911223344',
'SUPPORT',

View File

@ -1,64 +1,80 @@
-- ======================================================
-- Reset sequences for LMS tables
-- Reset sequences for LMS tables (PostgreSQL)
-- ======================================================
-- users.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('users', 'id'),
COALESCE(MAX(id), 1)
)
FROM users;
COALESCE((SELECT MAX(id) FROM users), 1),
true
);
-- assessment_questions.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('courses', 'id'),
COALESCE(MAX(id), 1)
)
FROM courses;
pg_get_serial_sequence('assessment_questions', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_questions), 1),
true
);
-- assessment_question_options.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('course_modules', 'id'),
COALESCE(MAX(id), 1)
)
FROM course_modules;
pg_get_serial_sequence('assessment_question_options', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_question_options), 1),
true
);
-- assessment_short_answers.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('lessons', 'id'),
COALESCE(MAX(id), 1)
)
FROM lessons;
pg_get_serial_sequence('assessment_short_answers', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_short_answers), 1),
true
);
-- assessment_attempts.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('enrollments', 'id'),
COALESCE(MAX(id), 1)
)
FROM enrollments;
pg_get_serial_sequence('assessment_attempts', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_attempts), 1),
true
);
-- assessment_attempt_questions.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('assessments', 'id'),
COALESCE(MAX(id), 1)
)
FROM assessments;
pg_get_serial_sequence('assessment_attempt_questions', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_attempt_questions), 1),
true
);
-- assessment_attempt_answers.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('assessment_submissions', 'id'),
COALESCE(MAX(id), 1)
)
FROM assessment_submissions;
pg_get_serial_sequence('assessment_attempt_answers', 'id'),
COALESCE((SELECT MAX(id) FROM assessment_attempt_answers), 1),
true
);
-- refresh_tokens.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('refresh_tokens', 'id'),
COALESCE((SELECT MAX(id) FROM refresh_tokens), 1),
true
);
-- otps.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('otps', 'id'),
COALESCE((SELECT MAX(id) FROM otps), 1),
true
);
-- notifications.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('notifications', 'id'),
COALESCE(MAX(id), 1)
)
FROM notifications;
COALESCE((SELECT MAX(id) FROM notifications), 1),
true
);
-- SELECT setval(
-- pg_get_serial_sequence('referral_codes', 'id'),
-- COALESCE(MAX(id), 1)
-- )
-- FROM referral_codes;
-- SELECT setval(
-- pg_get_serial_sequence('user_referrals', 'id'),
-- COALESCE(MAX(id), 1)
-- )
-- FROM user_referrals;
-- reported_issues.id (BIGSERIAL)
SELECT setval(
pg_get_serial_sequence('reported_issues', 'id'),
COALESCE((SELECT MAX(id) FROM reported_issues), 1),
true
);

View File

@ -1,10 +1,13 @@
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
user_name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
phone_number VARCHAR(20) UNIQUE,
first_name VARCHAR(255),
last_name VARCHAR(255),
gender VARCHAR(255),
birth_day DATE,
email VARCHAR(255),
phone_number VARCHAR(20),
role VARCHAR(50) NOT NULL, -- SUPER_ADMIN, INSTRUCTOR, STUDENT, SUPPORT
password BYTEA NOT NULL,
@ -19,20 +22,22 @@ CREATE TABLE IF NOT EXISTS users (
learning_goal TEXT,
language_goal TEXT,
language_challange TEXT,
favoutite_topic TEXT,
favourite_topic TEXT,
initial_assessment_completed BOOLEAN NOT NULL DEFAULT FALSE,
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
phone_verified BOOLEAN NOT NULL DEFAULT FALSE,
status VARCHAR(50) NOT NULL, -- PENDING, ACTIVE, SUSPENDED, DEACTIVATED
last_login TIMESTAMPTZ,
profile_completed BOOLEAN NOT NULL DEFAULT FALSE,
profile_completed BOOLEAN,
profile_picture_url TEXT,
preferred_language VARCHAR(50),
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ,
-- Enforce: at least one contact method must be provided
CONSTRAINT users_email_or_phone_required
CHECK (email IS NOT NULL OR phone_number IS NOT NULL)
);
@ -167,7 +172,7 @@ CREATE TABLE refresh_tokens (
CREATE TABLE otps (
id BIGSERIAL PRIMARY KEY,
user_name VARCHAR(100) NOT NULL,
user_id BIGSERIAL NOT NULL,
sent_to VARCHAR(255) NOT NULL,
medium VARCHAR(50) NOT NULL, -- email, sms
otp_for VARCHAR(50) NOT NULL, -- register, reset

View File

@ -5,11 +5,11 @@ SET
used = FALSE,
used_at = NULL,
expires_at = $3
WHERE user_name = $1;
WHERE user_id = $1;
-- name: CreateOtp :exec
INSERT INTO otps (
user_name,
user_id,
sent_to,
medium,
otp_for,
@ -19,9 +19,9 @@ INSERT INTO otps (
VALUES ($1, $2, $3, $4, $5, $6);
-- name: GetOtp :one
SELECT id, user_name, sent_to, medium, otp_for, otp, used, used_at, created_at, expires_at
SELECT id, user_id, sent_to, medium, otp_for, otp, used, used_at, created_at, expires_at
FROM otps
WHERE user_name = $1
WHERE user_id = $1
ORDER BY created_at DESC LIMIT 1;
-- name: MarkOtpAsUsed :exec

View File

@ -2,7 +2,7 @@
SELECT
CASE WHEN status = 'PENDING' THEN true ELSE false END AS is_pending
FROM users
WHERE user_name = $1
WHERE id = $1
LIMIT 1;
-- name: IsProfileCompleted :one
@ -16,14 +16,15 @@ LIMIT 1;
SELECT
CASE WHEN COUNT(*) = 0 THEN true ELSE false END AS is_unique
FROM users
WHERE user_name = $1;
WHERE id = $1;
-- name: CreateUser :one
INSERT INTO users (
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -38,7 +39,7 @@ INSERT INTO users (
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
email_verified,
@ -52,37 +53,39 @@ INSERT INTO users (
VALUES (
$1, -- first_name
$2, -- last_name
$3, -- user_name
$4, -- email
$5, -- phone_number
$6, -- role
$7, -- password
$8, -- age
$9, -- education_level
$10, -- country
$11, -- region
$3, -- gender
$4, -- birth_day
$5, -- email
$6, -- phone_number
$7, -- role
$8, -- password
$9, -- age
$10, -- education_level
$11, -- country
$12, -- region
$12, -- nick_name
$13, -- occupation
$14, -- learning_goal
$15, -- language_goal
$16, -- language_challange
$17, -- favoutite_topic
$13, -- nick_name
$14, -- occupation
$15, -- learning_goal
$16, -- language_goal
$17, -- language_challange
$18, -- favourite_topic
$18, -- initial_assessment_completed
$19, -- email_verified
$20, -- phone_verified
$21, -- status
$22, -- profile_completed
$23, -- profile_picture_url
$24, -- preferred_language
$19, -- initial_assessment_completed
$20, -- email_verified
$21, -- phone_verified
$22, -- status
$23, -- profile_completed
$24, -- profile_picture_url
$25, -- preferred_language
CURRENT_TIMESTAMP
)
RETURNING
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -96,7 +99,7 @@ RETURNING
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
email_verified,
@ -119,7 +122,8 @@ SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -132,7 +136,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
profile_picture_url,
preferred_language,
@ -163,7 +167,8 @@ SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -177,7 +182,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
profile_picture_url,
@ -205,27 +210,32 @@ UPDATE users
SET
first_name = COALESCE($1, first_name),
last_name = COALESCE($2, last_name),
user_name = COALESCE($3, user_name),
knowledge_level = COALESCE($4, knowledge_level),
age = COALESCE($5, age),
education_level = COALESCE($6, education_level),
country = COALESCE($7, country),
region = COALESCE($8, region),
nick_name = COALESCE($9, nick_name),
occupation = COALESCE($10, occupation),
learning_goal = COALESCE($11, learning_goal),
language_goal = COALESCE($12, language_goal),
language_challange = COALESCE($13, language_challange),
favoutite_topic = COALESCE($14, favoutite_topic),
initial_assessment_completed = COALESCE($15, initial_assessment_completed),
email_verified = COALESCE($16, email_verified),
phone_verified = COALESCE($17, phone_verified),
status = COALESCE($18, status),
profile_completed = COALESCE($19, profile_completed),
profile_picture_url = COALESCE($20, profile_picture_url),
preferred_language = COALESCE($21, preferred_language),
-- email = COALESCE($3, email),
-- phone_number = COALESCE($4, phone_number),
knowledge_level = COALESCE($3, knowledge_level),
age = COALESCE($4, age),
education_level = COALESCE($5, education_level),
country = COALESCE($6, country),
region = COALESCE($7, region),
nick_name = COALESCE($8, nick_name),
occupation = COALESCE($9, occupation),
learning_goal = COALESCE($10, learning_goal),
language_goal = COALESCE($11, language_goal),
language_challange = COALESCE($12, language_challange),
favourite_topic = COALESCE($13, favourite_topic),
initial_assessment_completed = COALESCE($14, initial_assessment_completed),
-- email_verified = COALESCE($15, email_verified),
-- phone_verified = COALESCE($16, phone_verified),
-- status = COALESCE($19, status),
profile_completed = COALESCE($15, profile_completed),
profile_picture_url = COALESCE($16, profile_picture_url),
preferred_language = COALESCE($17, preferred_language),
gender = COALESCE($18, gender),
birth_day = COALESCE($19, gender),
updated_at = CURRENT_TIMESTAMP
WHERE id = $22;
WHERE id = $20;
-- name: DeleteUser :exec
DELETE FROM users
@ -240,47 +250,47 @@ SELECT
SELECT 1 FROM users u2 WHERE u2.email = $2
) AS email_exists;
-- name: GetUserByUserName :one
SELECT
id,
first_name,
last_name,
user_name,
email,
phone_number,
role,
password,
age,
education_level,
country,
region,
-- -- name: GetUserByUserName :one
-- SELECT
-- id,
-- first_name,
-- last_name,
-- email,
-- phone_number,
-- role,
-- password,
-- age,
-- education_level,
-- country,
-- region,
nick_name,
occupation,
learning_goal,
language_goal,
language_challange,
favoutite_topic,
-- nick_name,
-- occupation,
-- learning_goal,
-- language_goal,
-- language_challange,
-- favourite_topic,
email_verified,
phone_verified,
status,
profile_completed,
last_login,
profile_picture_url,
preferred_language,
created_at,
updated_at
FROM users
WHERE user_name = $1 AND $1 IS NOT NULL
LIMIT 1;
-- email_verified,
-- phone_verified,
-- status,
-- profile_completed,
-- last_login,
-- profile_picture_url,
-- preferred_language,
-- created_at,
-- updated_at
-- FROM users
-- WHERE user_name = $1 AND $1 IS NOT NULL
-- LIMIT 1;
-- name: GetUserByEmailPhone :one
SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -295,7 +305,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
email_verified,
phone_verified,
@ -316,7 +326,7 @@ UPDATE users
SET
password = $1,
updated_at = CURRENT_TIMESTAMP
WHERE user_name = $2;
WHERE id = $2;
-- name: UpdateUserStatus :exec
UPDATE users

View File

@ -146,7 +146,7 @@ type Notification struct {
type Otp struct {
ID int64 `json:"id"`
UserName string `json:"user_name"`
UserID int64 `json:"user_id"`
SentTo string `json:"sent_to"`
Medium string `json:"medium"`
OtpFor string `json:"otp_for"`
@ -213,9 +213,10 @@ type ReportedIssue struct {
type User struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -230,13 +231,13 @@ type User struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
LastLogin pgtype.Timestamptz `json:"last_login"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
CreatedAt pgtype.Timestamptz `json:"created_at"`

View File

@ -13,7 +13,7 @@ import (
const CreateOtp = `-- name: CreateOtp :exec
INSERT INTO otps (
user_name,
user_id,
sent_to,
medium,
otp_for,
@ -24,7 +24,7 @@ VALUES ($1, $2, $3, $4, $5, $6)
`
type CreateOtpParams struct {
UserName string `json:"user_name"`
UserID int64 `json:"user_id"`
SentTo string `json:"sent_to"`
Medium string `json:"medium"`
OtpFor string `json:"otp_for"`
@ -34,7 +34,7 @@ type CreateOtpParams struct {
func (q *Queries) CreateOtp(ctx context.Context, arg CreateOtpParams) error {
_, err := q.db.Exec(ctx, CreateOtp,
arg.UserName,
arg.UserID,
arg.SentTo,
arg.Medium,
arg.OtpFor,
@ -45,15 +45,15 @@ func (q *Queries) CreateOtp(ctx context.Context, arg CreateOtpParams) error {
}
const GetOtp = `-- name: GetOtp :one
SELECT id, user_name, sent_to, medium, otp_for, otp, used, used_at, created_at, expires_at
SELECT id, user_id, sent_to, medium, otp_for, otp, used, used_at, created_at, expires_at
FROM otps
WHERE user_name = $1
WHERE user_id = $1
ORDER BY created_at DESC LIMIT 1
`
type GetOtpRow struct {
ID int64 `json:"id"`
UserName string `json:"user_name"`
UserID int64 `json:"user_id"`
SentTo string `json:"sent_to"`
Medium string `json:"medium"`
OtpFor string `json:"otp_for"`
@ -64,12 +64,12 @@ type GetOtpRow struct {
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
}
func (q *Queries) GetOtp(ctx context.Context, userName string) (GetOtpRow, error) {
row := q.db.QueryRow(ctx, GetOtp, userName)
func (q *Queries) GetOtp(ctx context.Context, userID int64) (GetOtpRow, error) {
row := q.db.QueryRow(ctx, GetOtp, userID)
var i GetOtpRow
err := row.Scan(
&i.ID,
&i.UserName,
&i.UserID,
&i.SentTo,
&i.Medium,
&i.OtpFor,
@ -105,16 +105,16 @@ SET
used = FALSE,
used_at = NULL,
expires_at = $3
WHERE user_name = $1
WHERE user_id = $1
`
type UpdateExpiredOtpParams struct {
UserName string `json:"user_name"`
UserID int64 `json:"user_id"`
Otp string `json:"otp"`
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
}
func (q *Queries) UpdateExpiredOtp(ctx context.Context, arg UpdateExpiredOtpParams) error {
_, err := q.db.Exec(ctx, UpdateExpiredOtp, arg.UserName, arg.Otp, arg.ExpiresAt)
_, err := q.db.Exec(ctx, UpdateExpiredOtp, arg.UserID, arg.Otp, arg.ExpiresAt)
return err
}

View File

@ -42,7 +42,8 @@ const CreateUser = `-- name: CreateUser :one
INSERT INTO users (
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -57,7 +58,7 @@ INSERT INTO users (
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
email_verified,
@ -71,37 +72,39 @@ INSERT INTO users (
VALUES (
$1, -- first_name
$2, -- last_name
$3, -- user_name
$4, -- email
$5, -- phone_number
$6, -- role
$7, -- password
$8, -- age
$9, -- education_level
$10, -- country
$11, -- region
$3, -- gender
$4, -- birth_day
$5, -- email
$6, -- phone_number
$7, -- role
$8, -- password
$9, -- age
$10, -- education_level
$11, -- country
$12, -- region
$12, -- nick_name
$13, -- occupation
$14, -- learning_goal
$15, -- language_goal
$16, -- language_challange
$17, -- favoutite_topic
$13, -- nick_name
$14, -- occupation
$15, -- learning_goal
$16, -- language_goal
$17, -- language_challange
$18, -- favourite_topic
$18, -- initial_assessment_completed
$19, -- email_verified
$20, -- phone_verified
$21, -- status
$22, -- profile_completed
$23, -- profile_picture_url
$24, -- preferred_language
$19, -- initial_assessment_completed
$20, -- email_verified
$21, -- phone_verified
$22, -- status
$23, -- profile_completed
$24, -- profile_picture_url
$25, -- preferred_language
CURRENT_TIMESTAMP
)
RETURNING
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -115,7 +118,7 @@ RETURNING
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
email_verified,
@ -129,9 +132,10 @@ RETURNING
`
type CreateUserParams struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -145,21 +149,22 @@ type CreateUserParams struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
}
type CreateUserRow struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -172,12 +177,12 @@ type CreateUserRow struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
@ -188,7 +193,8 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
row := q.db.QueryRow(ctx, CreateUser,
arg.FirstName,
arg.LastName,
arg.UserName,
arg.Gender,
arg.BirthDay,
arg.Email,
arg.PhoneNumber,
arg.Role,
@ -202,7 +208,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
arg.LearningGoal,
arg.LanguageGoal,
arg.LanguageChallange,
arg.FavoutiteTopic,
arg.FavouriteTopic,
arg.InitialAssessmentCompleted,
arg.EmailVerified,
arg.PhoneVerified,
@ -216,7 +222,8 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Gender,
&i.BirthDay,
&i.Email,
&i.PhoneNumber,
&i.Role,
@ -229,7 +236,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.FavouriteTopic,
&i.InitialAssessmentCompleted,
&i.EmailVerified,
&i.PhoneVerified,
@ -259,7 +266,8 @@ SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -272,7 +280,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
profile_picture_url,
preferred_language,
@ -306,9 +314,10 @@ type GetAllUsersParams struct {
type GetAllUsersRow struct {
TotalCount int64 `json:"total_count"`
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -321,14 +330,14 @@ type GetAllUsersRow struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
@ -354,7 +363,8 @@ func (q *Queries) GetAllUsers(ctx context.Context, arg GetAllUsersParams) ([]Get
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Gender,
&i.BirthDay,
&i.Email,
&i.PhoneNumber,
&i.Role,
@ -367,7 +377,7 @@ func (q *Queries) GetAllUsers(ctx context.Context, arg GetAllUsersParams) ([]Get
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.FavouriteTopic,
&i.InitialAssessmentCompleted,
&i.ProfilePictureUrl,
&i.PreferredLanguage,
@ -402,11 +412,15 @@ func (q *Queries) GetTotalUsers(ctx context.Context, role string) (int64, error)
}
const GetUserByEmailPhone = `-- name: GetUserByEmailPhone :one
SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -421,7 +435,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
email_verified,
phone_verified,
@ -445,9 +459,10 @@ type GetUserByEmailPhoneParams struct {
type GetUserByEmailPhoneRow struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -461,11 +476,11 @@ type GetUserByEmailPhoneRow struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
LastLogin pgtype.Timestamptz `json:"last_login"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
@ -473,6 +488,39 @@ type GetUserByEmailPhoneRow struct {
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
// -- name: GetUserByUserName :one
// SELECT
//
// id,
// first_name,
// last_name,
// email,
// phone_number,
// role,
// password,
// age,
// education_level,
// country,
// region,
// nick_name,
// occupation,
// learning_goal,
// language_goal,
// language_challange,
// favourite_topic,
// email_verified,
// phone_verified,
// status,
// profile_completed,
// last_login,
// profile_picture_url,
// preferred_language,
// created_at,
// updated_at
//
// FROM users
// WHERE user_name = $1 AND $1 IS NOT NULL
// LIMIT 1;
func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPhoneParams) (GetUserByEmailPhoneRow, error) {
row := q.db.QueryRow(ctx, GetUserByEmailPhone, arg.Email, arg.PhoneNumber)
var i GetUserByEmailPhoneRow
@ -480,7 +528,8 @@ func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPho
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Gender,
&i.BirthDay,
&i.Email,
&i.PhoneNumber,
&i.Role,
@ -494,7 +543,7 @@ func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPho
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.FavouriteTopic,
&i.EmailVerified,
&i.PhoneVerified,
&i.Status,
@ -509,7 +558,7 @@ func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPho
}
const GetUserByID = `-- name: GetUserByID :one
SELECT id, first_name, last_name, user_name, email, phone_number, role, password, age, education_level, country, region, knowledge_level, nick_name, occupation, learning_goal, language_goal, language_challange, favoutite_topic, initial_assessment_completed, email_verified, phone_verified, status, last_login, profile_completed, profile_picture_url, preferred_language, created_at, updated_at
SELECT id, first_name, last_name, gender, birth_day, email, phone_number, role, password, age, education_level, country, region, knowledge_level, nick_name, occupation, learning_goal, language_goal, language_challange, favourite_topic, initial_assessment_completed, email_verified, phone_verified, status, last_login, profile_completed, profile_picture_url, preferred_language, created_at, updated_at
FROM users
WHERE id = $1
`
@ -521,7 +570,8 @@ func (q *Queries) GetUserByID(ctx context.Context, id int64) (User, error) {
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Gender,
&i.BirthDay,
&i.Email,
&i.PhoneNumber,
&i.Role,
@ -536,7 +586,7 @@ func (q *Queries) GetUserByID(ctx context.Context, id int64) (User, error) {
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.FavouriteTopic,
&i.InitialAssessmentCompleted,
&i.EmailVerified,
&i.PhoneVerified,
@ -551,107 +601,6 @@ func (q *Queries) GetUserByID(ctx context.Context, id int64) (User, error) {
return i, err
}
const GetUserByUserName = `-- name: GetUserByUserName :one
SELECT
id,
first_name,
last_name,
user_name,
email,
phone_number,
role,
password,
age,
education_level,
country,
region,
nick_name,
occupation,
learning_goal,
language_goal,
language_challange,
favoutite_topic,
email_verified,
phone_verified,
status,
profile_completed,
last_login,
profile_picture_url,
preferred_language,
created_at,
updated_at
FROM users
WHERE user_name = $1 AND $1 IS NOT NULL
LIMIT 1
`
type GetUserByUserNameRow struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
Password []byte `json:"password"`
Age pgtype.Int4 `json:"age"`
EducationLevel pgtype.Text `json:"education_level"`
Country pgtype.Text `json:"country"`
Region pgtype.Text `json:"region"`
NickName pgtype.Text `json:"nick_name"`
Occupation pgtype.Text `json:"occupation"`
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
LastLogin pgtype.Timestamptz `json:"last_login"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetUserByUserName(ctx context.Context, userName string) (GetUserByUserNameRow, error) {
row := q.db.QueryRow(ctx, GetUserByUserName, userName)
var i GetUserByUserNameRow
err := row.Scan(
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Email,
&i.PhoneNumber,
&i.Role,
&i.Password,
&i.Age,
&i.EducationLevel,
&i.Country,
&i.Region,
&i.NickName,
&i.Occupation,
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.EmailVerified,
&i.PhoneVerified,
&i.Status,
&i.ProfileCompleted,
&i.LastLogin,
&i.ProfilePictureUrl,
&i.PreferredLanguage,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const IsProfileCompleted = `-- name: IsProfileCompleted :one
SELECT
CASE WHEN profile_completed = true THEN true ELSE false END AS is_pending
@ -671,11 +620,11 @@ const IsUserNameUnique = `-- name: IsUserNameUnique :one
SELECT
CASE WHEN COUNT(*) = 0 THEN true ELSE false END AS is_unique
FROM users
WHERE user_name = $1
WHERE id = $1
`
func (q *Queries) IsUserNameUnique(ctx context.Context, userName string) (bool, error) {
row := q.db.QueryRow(ctx, IsUserNameUnique, userName)
func (q *Queries) IsUserNameUnique(ctx context.Context, id int64) (bool, error) {
row := q.db.QueryRow(ctx, IsUserNameUnique, id)
var is_unique bool
err := row.Scan(&is_unique)
return is_unique, err
@ -685,12 +634,12 @@ const IsUserPending = `-- name: IsUserPending :one
SELECT
CASE WHEN status = 'PENDING' THEN true ELSE false END AS is_pending
FROM users
WHERE user_name = $1
WHERE id = $1
LIMIT 1
`
func (q *Queries) IsUserPending(ctx context.Context, userName string) (bool, error) {
row := q.db.QueryRow(ctx, IsUserPending, userName)
func (q *Queries) IsUserPending(ctx context.Context, id int64) (bool, error) {
row := q.db.QueryRow(ctx, IsUserPending, id)
var is_pending bool
err := row.Scan(&is_pending)
return is_pending, err
@ -701,7 +650,8 @@ SELECT
id,
first_name,
last_name,
user_name,
gender,
birth_day,
email,
phone_number,
role,
@ -715,7 +665,7 @@ SELECT
learning_goal,
language_goal,
language_challange,
favoutite_topic,
favourite_topic,
initial_assessment_completed,
profile_picture_url,
@ -746,9 +696,10 @@ type SearchUserByNameOrPhoneParams struct {
type SearchUserByNameOrPhoneRow struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
Email pgtype.Text `json:"email"`
PhoneNumber pgtype.Text `json:"phone_number"`
Role string `json:"role"`
@ -761,14 +712,14 @@ type SearchUserByNameOrPhoneRow struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
@ -786,7 +737,8 @@ func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByN
&i.ID,
&i.FirstName,
&i.LastName,
&i.UserName,
&i.Gender,
&i.BirthDay,
&i.Email,
&i.PhoneNumber,
&i.Role,
@ -799,7 +751,7 @@ func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByN
&i.LearningGoal,
&i.LanguageGoal,
&i.LanguageChallange,
&i.FavoutiteTopic,
&i.FavouriteTopic,
&i.InitialAssessmentCompleted,
&i.ProfilePictureUrl,
&i.PreferredLanguage,
@ -825,16 +777,16 @@ UPDATE users
SET
password = $1,
updated_at = CURRENT_TIMESTAMP
WHERE user_name = $2
WHERE id = $2
`
type UpdatePasswordParams struct {
Password []byte `json:"password"`
UserName string `json:"user_name"`
ID int64 `json:"id"`
}
func (q *Queries) UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error {
_, err := q.db.Exec(ctx, UpdatePassword, arg.Password, arg.UserName)
_, err := q.db.Exec(ctx, UpdatePassword, arg.Password, arg.ID)
return err
}
@ -843,33 +795,37 @@ UPDATE users
SET
first_name = COALESCE($1, first_name),
last_name = COALESCE($2, last_name),
user_name = COALESCE($3, user_name),
knowledge_level = COALESCE($4, knowledge_level),
age = COALESCE($5, age),
education_level = COALESCE($6, education_level),
country = COALESCE($7, country),
region = COALESCE($8, region),
nick_name = COALESCE($9, nick_name),
occupation = COALESCE($10, occupation),
learning_goal = COALESCE($11, learning_goal),
language_goal = COALESCE($12, language_goal),
language_challange = COALESCE($13, language_challange),
favoutite_topic = COALESCE($14, favoutite_topic),
initial_assessment_completed = COALESCE($15, initial_assessment_completed),
email_verified = COALESCE($16, email_verified),
phone_verified = COALESCE($17, phone_verified),
status = COALESCE($18, status),
profile_completed = COALESCE($19, profile_completed),
profile_picture_url = COALESCE($20, profile_picture_url),
preferred_language = COALESCE($21, preferred_language),
-- email = COALESCE($3, email),
-- phone_number = COALESCE($4, phone_number),
knowledge_level = COALESCE($3, knowledge_level),
age = COALESCE($4, age),
education_level = COALESCE($5, education_level),
country = COALESCE($6, country),
region = COALESCE($7, region),
nick_name = COALESCE($8, nick_name),
occupation = COALESCE($9, occupation),
learning_goal = COALESCE($10, learning_goal),
language_goal = COALESCE($11, language_goal),
language_challange = COALESCE($12, language_challange),
favourite_topic = COALESCE($13, favourite_topic),
initial_assessment_completed = COALESCE($14, initial_assessment_completed),
-- email_verified = COALESCE($15, email_verified),
-- phone_verified = COALESCE($16, phone_verified),
-- status = COALESCE($19, status),
profile_completed = COALESCE($15, profile_completed),
profile_picture_url = COALESCE($16, profile_picture_url),
preferred_language = COALESCE($17, preferred_language),
gender = COALESCE($18, gender),
birth_day = COALESCE($19, gender),
updated_at = CURRENT_TIMESTAMP
WHERE id = $22
WHERE id = $20
`
type UpdateUserParams struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
KnowledgeLevel pgtype.Text `json:"knowledge_level"`
Age pgtype.Int4 `json:"age"`
EducationLevel pgtype.Text `json:"education_level"`
@ -880,14 +836,13 @@ type UpdateUserParams struct {
LearningGoal pgtype.Text `json:"learning_goal"`
LanguageGoal pgtype.Text `json:"language_goal"`
LanguageChallange pgtype.Text `json:"language_challange"`
FavoutiteTopic pgtype.Text `json:"favoutite_topic"`
FavouriteTopic pgtype.Text `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
Status string `json:"status"`
ProfileCompleted bool `json:"profile_completed"`
ProfileCompleted pgtype.Bool `json:"profile_completed"`
ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
PreferredLanguage pgtype.Text `json:"preferred_language"`
Gender pgtype.Text `json:"gender"`
BirthDay pgtype.Date `json:"birth_day"`
ID int64 `json:"id"`
}
@ -895,7 +850,6 @@ func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) error {
_, err := q.db.Exec(ctx, UpdateUser,
arg.FirstName,
arg.LastName,
arg.UserName,
arg.KnowledgeLevel,
arg.Age,
arg.EducationLevel,
@ -906,14 +860,13 @@ func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) error {
arg.LearningGoal,
arg.LanguageGoal,
arg.LanguageChallange,
arg.FavoutiteTopic,
arg.FavouriteTopic,
arg.InitialAssessmentCompleted,
arg.EmailVerified,
arg.PhoneVerified,
arg.Status,
arg.ProfileCompleted,
arg.ProfilePictureUrl,
arg.PreferredLanguage,
arg.Gender,
arg.BirthDay,
arg.ID,
)
return err

View File

@ -28,7 +28,7 @@ const (
type Otp struct {
ID int64
UserName string
UserID int64
SentTo string
Medium OtpMedium
For OtpFor

View File

@ -34,7 +34,9 @@ type User struct {
ID int64
FirstName string
LastName string
UserName string
Gender string
BirthDay time.Time `json:"birth_day"`
// UserName string
Email string
PhoneNumber string
Password []byte
@ -47,13 +49,13 @@ type User struct {
// Profile fields
KnowledgeLevel string
initial_assessment_completed bool
InitialAssessmentCompleted bool
NickName string
Occupation string
LearningGoal string
LanguageGoal string
LanguageChallange string
FavoutiteTopic string
FavouriteTopic string
EmailVerified bool
PhoneVerified bool
@ -72,7 +74,9 @@ type UserProfileResponse struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name,omitempty"`
Gender string `json:"gender"`
BirthDay time.Time `json:"birth_day"`
// UserName string `json:"user_name,omitempty"`
Email string `json:"email,omitempty"`
PhoneNumber string `json:"phone_number,omitempty"`
Role Role `json:"role"`
@ -89,7 +93,7 @@ type UserProfileResponse struct {
LearningGoal string `json:"learning_goal,omitempty"`
LanguageGoal string `json:"language_goal,omitempty"`
LanguageChallange string `json:"language_challange,omitempty"`
FavoutiteTopic string `json:"favoutite_topic,omitempty"`
FavouriteTopic string `json:"favoutite_topic,omitempty"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
@ -107,42 +111,26 @@ type UserProfileResponse struct {
type UserFilter struct {
Role string
Page ValidInt
PageSize ValidInt
Query ValidString
Page int64
PageSize int64
Query string
CreatedBefore ValidTime
CreatedAfter ValidTime
}
type RegisterUserReq struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
UserName string `json:"user_name"`
Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
Password string `json:"password"`
Role string `json:"role"`
OtpMedium OtpMedium `json:"otp_medium"`
// NickName string `json:"nick_name,omitempty"`
// Occupation string `json:"occupation,omitempty"`
// LearningGoal string `json:"learning_goal,omitempty"`
// LanguageGoal string `json:"language_goal,omitempty"`
// LanguageChallange string `json:"language_challange,omitempty"`
// FavoutiteTopic string `json:"favoutite_topic,omitempty"`
// Age int `json:"age,omitempty"`
// EducationLevel string `json:"education_level,omitempty"`
// Country string `json:"country,omitempty"`
// Region string `json:"region,omitempty"`
// PreferredLanguage string `json:"preferred_language,omitempty"`
}
type CreateUserReq struct {
FirstName string
LastName string
UserName string
Gender string `json:"gender"`
BirthDay time.Time `json:"birth_day"`
Email string
PhoneNumber string
Password string
@ -161,40 +149,58 @@ type CreateUserReq struct {
LearningGoal string
LanguageGoal string
LanguageChallange string
FavoutiteTopic string
FavouriteTopic string
PreferredLanguage string
}
type ResetPasswordReq struct {
UserName string
UserID int64
Password string
OtpCode string
}
type UpdateUserReq struct {
type UpdateUserStatusReq struct {
Status string
UserID int64
FirstName ValidString
LastName ValidString
UserName ValidString
Status ValidString
Age ValidInt
EducationLevel ValidString
Country ValidString
Region ValidString
// Profile fields
KnowledgeLevel ValidString
NickName ValidString
Occupation ValidString
LearningGoal ValidString
LanguageGoal ValidString
LanguageChallange ValidString
FavoutiteTopic ValidString
ProfileCompleted ValidBool
ProfilePictureURL ValidString
PreferredLanguage ValidString
}
type UpdateUserReq struct {
// Identity (enforced from auth context, not request body)
UserID int64 `json:"-"`
// Basic profile
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Gender string `json:"gender"`
BirthDay time.Time `json:"birth_day"`
// Contact (optional at least one must exist at DB level)
// Email string `json:"email"`
// PhoneNumber string `json:"phone_number"`
// Personal details
Age int64 `json:"age"`
EducationLevel string `json:"education_level"`
Country string `json:"country"`
Region string `json:"region"`
// Learning / profile
KnowledgeLevel string `json:"knowledge_level"`
NickName string `json:"nick_name"`
Occupation string `json:"occupation"`
LearningGoal string `json:"learning_goal"`
LanguageGoal string `json:"language_goal"`
LanguageChallange string `json:"language_challange"`
FavouriteTopic string `json:"favourite_topic"`
InitialAssessmentCompleted bool `json:"initial_assessment_completed"`
// EmailVerified bool `json:"email_verified"`
// PhoneVerified bool `json:"phone_verified"`
ProfileCompleted bool `json:"profile_completed"`
// Media & preferences
ProfilePictureURL string `json:"profile_picture_url"`
PreferredLanguage string `json:"preferred_language"`
}

View File

@ -9,7 +9,7 @@ import (
type UserStore interface {
IsProfileCompleted(ctx context.Context, userId int64) (bool, error)
UpdateUserStatus(ctx context.Context, user domain.UpdateUserReq) error
UpdateUserStatus(ctx context.Context, req domain.UpdateUserStatusReq) error
// GetCorrectOptionForQuestion(
// ctx context.Context,
// questionID int64,
@ -19,12 +19,12 @@ type UserStore interface {
// userID int64,
// ) (*dbgen.AssessmentAttempt, error)
UpdateUserKnowledgeLevel(ctx context.Context, userID int64, knowledgeLevel string) error
IsUserNameUnique(ctx context.Context, userName string) (bool, error)
IsUserPending(ctx context.Context, UserName string) (bool, error)
GetUserByUserName(
ctx context.Context,
userName string,
) (domain.User, error)
// IsUserNameUnique(ctx context.Context, userName string) (bool, error)
IsUserPending(ctx context.Context, userID int64) (bool, error)
// GetUserByUserName(
// ctx context.Context,
// userName string,
// ) (domain.User, error)
CreateUser(
ctx context.Context,
user domain.User,
@ -51,7 +51,7 @@ type UserStore interface {
search string,
role *string,
) ([]domain.User, error)
UpdateUser(ctx context.Context, user domain.User) error
UpdateUser(ctx context.Context, req domain.UpdateUserReq) error
DeleteUser(ctx context.Context, userID int64) error
CheckPhoneEmailExist(ctx context.Context, phone, email string) (phoneExists, emailExists bool, err error)
GetUserByEmailPhone(
@ -59,7 +59,7 @@ type UserStore interface {
email string,
phone string,
) (domain.User, error)
UpdatePassword(ctx context.Context, password, userName string) error
UpdatePassword(ctx context.Context, password string, userID int64) error
}
type SmsGateway interface {
SendSMSOTP(ctx context.Context, phoneNumber, otp string) error
@ -68,8 +68,8 @@ type EmailGateway interface {
SendEmailOTP(ctx context.Context, email string, otp string) error
}
type OtpStore interface {
UpdateOtp(ctx context.Context, otp, userName string) error
UpdateOtp(ctx context.Context, otp string, userID int64) error
MarkOtpAsUsed(ctx context.Context, otp domain.Otp) error
CreateOtp(ctx context.Context, otp domain.Otp) error
GetOtp(ctx context.Context, userName string) (domain.Otp, error)
GetOtp(ctx context.Context, userID int64) (domain.Otp, error)
}

View File

@ -118,9 +118,9 @@ func (s *Store) GetUserByEmailOrPhone(
return domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
FirstName: u.FirstName.String,
LastName: u.LastName.String,
// UserName: u.UserName,
Email: u.Email.String,
PhoneNumber: u.PhoneNumber.String,
Password: u.Password,
@ -136,7 +136,7 @@ func (s *Store) GetUserByEmailOrPhone(
Status: domain.UserStatus(u.Status),
LastLogin: lastLogin,
ProfileCompleted: u.ProfileCompleted,
ProfileCompleted: u.ProfileCompleted.Bool,
ProfilePictureURL: u.ProfilePictureUrl.String,
PreferredLanguage: u.PreferredLanguage.String,

View File

@ -16,9 +16,9 @@ import (
// Interface for creating new otp store
func NewOTPStore(s *Store) ports.OtpStore { return s }
func (s *Store) UpdateOtp(ctx context.Context, otp, userName string) error {
func (s *Store) UpdateOtp(ctx context.Context, otp string, userId int64) error {
return s.queries.UpdateExpiredOtp(ctx, dbgen.UpdateExpiredOtpParams{
UserName: userName,
UserID: userId,
Otp: otp,
ExpiresAt: pgtype.Timestamptz{
Time: time.Now().Add(5 * time.Minute),
@ -29,7 +29,7 @@ func (s *Store) UpdateOtp(ctx context.Context, otp, userName string) error {
func (s *Store) CreateOtp(ctx context.Context, otp domain.Otp) error {
return s.queries.CreateOtp(ctx, dbgen.CreateOtpParams{
UserName: otp.UserName,
UserID: otp.UserID,
SentTo: otp.SentTo,
Medium: string(otp.Medium),
OtpFor: string(otp.For),
@ -41,10 +41,10 @@ func (s *Store) CreateOtp(ctx context.Context, otp domain.Otp) error {
})
}
func (s *Store) GetOtp(ctx context.Context, userName string) (domain.Otp, error) {
row, err := s.queries.GetOtp(ctx, userName)
func (s *Store) GetOtp(ctx context.Context, userID int64) (domain.Otp, error) {
row, err := s.queries.GetOtp(ctx, userID)
if err != nil {
fmt.Printf("OTP REPO error: %v userName: %v\n", err, userName)
fmt.Printf("OTP REPO error: %v userName: %v\n", err, userID)
if err == sql.ErrNoRows {
return domain.Otp{}, domain.ErrOtpNotFound
}
@ -52,7 +52,7 @@ func (s *Store) GetOtp(ctx context.Context, userName string) (domain.Otp, error)
}
return domain.Otp{
ID: row.ID,
UserName: row.UserName,
UserID: row.UserID,
SentTo: row.SentTo,
Medium: domain.OtpMedium(row.Medium),
For: domain.OtpFor(row.OtpFor),

View File

@ -34,8 +34,8 @@ func (s *Store) UpdateUserKnowledgeLevel(ctx context.Context, userID int64, know
})
}
func (s *Store) IsUserPending(ctx context.Context, UserName string) (bool, error) {
isPending, err := s.queries.IsUserPending(ctx, UserName)
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
@ -45,18 +45,18 @@ func (s *Store) IsUserPending(ctx context.Context, UserName string) (bool, error
return isPending, nil
}
func (s *Store) IsUserNameUnique(ctx context.Context, userName string) (bool, error) {
isUnique, err := s.queries.IsUserNameUnique(ctx, userName)
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, user domain.UpdateUserReq) error {
func (s *Store) UpdateUserStatus(ctx context.Context, req domain.UpdateUserStatusReq) error {
return s.queries.UpdateUserStatus(ctx, dbgen.UpdateUserStatusParams{
Status: user.Status.Value,
ID: user.UserID,
Status: req.Status,
ID: req.UserID,
})
}
@ -66,9 +66,17 @@ func (s *Store) CreateUserWithoutOtp(
) (domain.User, error) {
userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
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 != ""},
@ -101,9 +109,9 @@ func (s *Store) CreateUserWithoutOtp(
String: user.LanguageChallange,
Valid: user.LanguageChallange != "",
},
FavoutiteTopic: pgtype.Text{
String: user.FavoutiteTopic,
Valid: user.FavoutiteTopic != "",
FavouriteTopic: pgtype.Text{
String: user.FavouriteTopic,
Valid: user.FavouriteTopic != "",
},
EmailVerified: user.EmailVerified,
@ -114,7 +122,10 @@ func (s *Store) CreateUserWithoutOtp(
Valid: user.ProfilePictureURL != "",
},
Status: string(user.Status),
ProfileCompleted: user.ProfileCompleted,
ProfileCompleted: pgtype.Bool{
Bool: user.ProfileCompleted,
Valid: true,
},
PreferredLanguage: pgtype.Text{
String: user.PreferredLanguage,
Valid: user.PreferredLanguage != "",
@ -149,9 +160,17 @@ func (s *Store) CreateUser(
}
userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
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 != ""},
@ -169,7 +188,7 @@ func (s *Store) CreateUser(
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 != ""},
FavoutiteTopic: pgtype.Text{String: user.FavoutiteTopic, Valid: user.FavoutiteTopic != ""},
FavouriteTopic: pgtype.Text{String: user.FavouriteTopic, Valid: user.FavouriteTopic != ""},
EmailVerified: user.EmailVerified,
PhoneVerified: user.PhoneVerified,
@ -179,7 +198,10 @@ func (s *Store) CreateUser(
Valid: user.ProfilePictureURL != "",
},
Status: string(user.Status),
ProfileCompleted: user.ProfileCompleted,
ProfileCompleted: pgtype.Bool{
Bool: user.ProfileCompleted,
Valid: true,
},
PreferredLanguage: pgtype.Text{
String: user.PreferredLanguage,
Valid: user.PreferredLanguage != "",
@ -223,9 +245,11 @@ func (s *Store) GetUserByID(
return domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
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),
@ -240,14 +264,14 @@ func (s *Store) GetUserByID(
LearningGoal: u.LearningGoal.String,
LanguageGoal: u.LanguageGoal.String,
LanguageChallange: u.LanguageChallange.String,
FavoutiteTopic: u.FavoutiteTopic.String,
FavouriteTopic: u.FavouriteTopic.String,
EmailVerified: u.EmailVerified,
PhoneVerified: u.PhoneVerified,
Status: domain.UserStatus(u.Status),
LastLogin: lastLogin,
ProfileCompleted: u.ProfileCompleted,
ProfileCompleted: u.ProfileCompleted.Bool,
ProfilePictureURL: u.ProfilePictureUrl.String,
PreferredLanguage: u.PreferredLanguage.String,
@ -323,9 +347,11 @@ func (s *Store) GetAllUsers(
users = append(users, domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
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),
@ -340,14 +366,14 @@ func (s *Store) GetAllUsers(
LearningGoal: u.LearningGoal.String,
LanguageGoal: u.LanguageGoal.String,
LanguageChallange: u.LanguageChallange.String,
FavoutiteTopic: u.FavoutiteTopic.String,
FavouriteTopic: u.FavouriteTopic.String,
EmailVerified: u.EmailVerified,
PhoneVerified: u.PhoneVerified,
Status: domain.UserStatus(u.Status),
ProfilePictureURL: u.ProfilePictureUrl.String,
ProfileCompleted: u.ProfileCompleted,
ProfileCompleted: u.ProfileCompleted.Bool,
PreferredLanguage: u.PreferredLanguage.String,
CreatedAt: u.CreatedAt.Time,
@ -408,9 +434,11 @@ func (s *Store) SearchUserByNameOrPhone(
users = append(users, domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
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),
@ -425,13 +453,13 @@ func (s *Store) SearchUserByNameOrPhone(
LearningGoal: u.LearningGoal.String,
LanguageGoal: u.LanguageGoal.String,
LanguageChallange: u.LanguageChallange.String,
FavoutiteTopic: u.FavoutiteTopic.String,
FavouriteTopic: u.FavouriteTopic.String,
EmailVerified: u.EmailVerified,
PhoneVerified: u.PhoneVerified,
Status: domain.UserStatus(u.Status),
ProfileCompleted: u.ProfileCompleted,
ProfileCompleted: u.ProfileCompleted.Bool,
ProfilePictureURL: u.ProfilePictureUrl.String,
PreferredLanguage: u.PreferredLanguage.String,
@ -446,69 +474,44 @@ func (s *Store) SearchUserByNameOrPhone(
// UpdateUser updates basic user info
func (s *Store) UpdateUser(
ctx context.Context,
user domain.User,
req domain.UpdateUserReq,
) error {
return s.queries.UpdateUser(ctx, dbgen.UpdateUserParams{
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
Age: pgtype.Int4{
Int32: int32(user.Age),
Valid: user.Age > 0,
FirstName: pgtype.Text{String: req.FirstName, Valid: req.FirstName != ""},
LastName: pgtype.Text{String: req.LastName, Valid: req.LastName != ""},
Gender: pgtype.Text{
String: req.Gender,
Valid: req.Gender != "",
},
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 != "",
BirthDay: pgtype.Date{
Time: req.BirthDay,
Valid: true,
},
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 != "",
},
FavoutiteTopic: pgtype.Text{
String: user.FavoutiteTopic,
Valid: user.FavoutiteTopic != "",
Age: pgtype.Int4{Int32: int32(req.Age), Valid: req.Age > 0},
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 != ""},
ProfileCompleted: pgtype.Bool{
Bool: req.ProfileCompleted,
Valid: true,
},
Status: string(user.Status),
ProfileCompleted: user.ProfileCompleted,
ProfilePictureUrl: pgtype.Text{
String: user.ProfilePictureURL,
Valid: user.ProfilePictureURL != "",
},
PreferredLanguage: pgtype.Text{
String: user.PreferredLanguage,
Valid: user.PreferredLanguage != "",
},
ProfilePictureUrl: pgtype.Text{String: req.ProfilePictureURL, Valid: req.ProfilePictureURL != ""},
PreferredLanguage: pgtype.Text{String: req.PreferredLanguage, Valid: req.PreferredLanguage != ""},
ID: user.ID,
ID: req.UserID,
})
}
// DeleteUser removes a user
@ -529,64 +532,64 @@ func (s *Store) CheckPhoneEmailExist(ctx context.Context, phone, email string) (
return res.PhoneExists, res.EmailExists, nil
}
func (s *Store) GetUserByUserName(
ctx context.Context,
userName string,
) (domain.User, error) {
// func (s *Store) GetUserByUserName(
// ctx context.Context,
// userName string,
// ) (domain.User, error) {
u, err := s.queries.GetUserByUserName(ctx, userName)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return domain.User{}, authentication.ErrUserNotFound
}
return domain.User{}, err
}
// u, err := s.queries.GetUserByUserName(ctx, userName)
// if err != nil {
// if errors.Is(err, pgx.ErrNoRows) {
// return domain.User{}, authentication.ErrUserNotFound
// }
// return domain.User{}, err
// }
var lastLogin *time.Time
if u.LastLogin.Valid {
lastLogin = &u.LastLogin.Time
}
// var lastLogin *time.Time
// if u.LastLogin.Valid {
// lastLogin = &u.LastLogin.Time
// }
var updatedAt *time.Time
if u.UpdatedAt.Valid {
updatedAt = &u.UpdatedAt.Time
}
// var updatedAt *time.Time
// if u.UpdatedAt.Valid {
// updatedAt = &u.UpdatedAt.Time
// }
return domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
Email: u.Email.String,
PhoneNumber: u.PhoneNumber.String,
Password: u.Password,
Role: domain.Role(u.Role),
// return domain.User{
// ID: u.ID,
// FirstName: u.FirstName,
// LastName: u.LastName,
// UserName: u.UserName,
// Email: u.Email.String,
// PhoneNumber: u.PhoneNumber.String,
// Password: u.Password,
// Role: domain.Role(u.Role),
Age: int(u.Age.Int32),
EducationLevel: u.EducationLevel.String,
Country: u.Country.String,
Region: u.Region.String,
// Age: int(u.Age.Int32),
// 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,
FavoutiteTopic: u.FavoutiteTopic.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),
// EmailVerified: u.EmailVerified,
// PhoneVerified: u.PhoneVerified,
// Status: domain.UserStatus(u.Status),
LastLogin: lastLogin,
ProfileCompleted: u.ProfileCompleted,
ProfilePictureURL: u.ProfilePictureUrl.String,
PreferredLanguage: u.PreferredLanguage.String,
// LastLogin: lastLogin,
// ProfileCompleted: u.ProfileCompleted,
// ProfilePictureURL: u.ProfilePictureUrl.String,
// PreferredLanguage: u.PreferredLanguage.String,
CreatedAt: u.CreatedAt.Time,
UpdatedAt: updatedAt,
}, nil
}
// CreatedAt: u.CreatedAt.Time,
// UpdatedAt: updatedAt,
// }, nil
// }
// GetUserByEmail retrieves a user by email and organization
func (s *Store) GetUserByEmailPhone(
@ -624,9 +627,11 @@ func (s *Store) GetUserByEmailPhone(
return domain.User{
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
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,
@ -642,7 +647,7 @@ func (s *Store) GetUserByEmailPhone(
LearningGoal: u.LearningGoal.String,
LanguageGoal: u.LanguageGoal.String,
LanguageChallange: u.LanguageChallange.String,
FavoutiteTopic: u.FavoutiteTopic.String,
FavouriteTopic: u.FavouriteTopic.String,
EmailVerified: u.EmailVerified,
PhoneVerified: u.PhoneVerified,
@ -650,7 +655,7 @@ func (s *Store) GetUserByEmailPhone(
ProfilePictureURL: u.ProfilePictureUrl.String,
LastLogin: lastLogin,
ProfileCompleted: u.ProfileCompleted,
ProfileCompleted: u.ProfileCompleted.Bool,
PreferredLanguage: u.PreferredLanguage.String,
CreatedAt: u.CreatedAt.Time,
@ -659,10 +664,10 @@ func (s *Store) GetUserByEmailPhone(
}
// UpdatePassword updates a user's password
func (s *Store) UpdatePassword(ctx context.Context, password, userName string) error {
func (s *Store) UpdatePassword(ctx context.Context, password string, userID int64) error {
return s.queries.UpdatePassword(ctx, dbgen.UpdatePasswordParams{
Password: []byte(password),
UserName: userName,
ID: userID,
})
}
@ -675,9 +680,11 @@ func mapCreateUserResult(
return domain.User{
ID: userRes.ID,
FirstName: userRes.FirstName,
LastName: userRes.LastName,
UserName: userRes.UserName,
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),
@ -693,13 +700,13 @@ func mapCreateUserResult(
LearningGoal: userRes.LearningGoal.String,
LanguageGoal: userRes.LanguageGoal.String,
LanguageChallange: userRes.LanguageChallange.String,
FavoutiteTopic: userRes.FavoutiteTopic.String,
FavouriteTopic: userRes.FavouriteTopic.String,
EmailVerified: userRes.EmailVerified,
PhoneVerified: userRes.PhoneVerified,
Status: domain.UserStatus(userRes.Status),
ProfileCompleted: userRes.ProfileCompleted,
ProfileCompleted: userRes.ProfileCompleted.Bool,
PreferredLanguage: userRes.PreferredLanguage.String,
CreatedAt: userRes.CreatedAt.Time,

View File

@ -17,7 +17,7 @@ func (s *Service) VerifyOtp(ctx context.Context, email, phone, otpCode string) e
return err
}
// 1. Retrieve the OTP from the store
storedOtp, err := s.otpStore.GetOtp(ctx, user.UserName)
storedOtp, err := s.otpStore.GetOtp(ctx, user.ID)
if err != nil {
return err // could be ErrOtpNotFound or other DB errors
}
@ -50,12 +50,9 @@ func (s *Service) VerifyOtp(ctx context.Context, email, phone, otpCode string) e
// return err
// }
newUser := domain.UpdateUserReq{
newUser := domain.UpdateUserStatusReq{
UserID: user.ID,
Status: domain.ValidString{
Value: string(domain.UserStatusActive),
Valid: true,
},
Status: string(domain.UserStatusActive),
}
s.userStore.UpdateUserStatus(ctx, newUser)
@ -80,7 +77,7 @@ func (s *Service) ResendOtp(
otpCode,
)
otp, err := s.otpStore.GetOtp(ctx, user.UserName)
otp, err := s.otpStore.GetOtp(ctx, user.ID)
if err != nil {
return err
}
@ -106,14 +103,14 @@ func (s *Service) ResendOtp(
return fmt.Errorf("invalid otp medium: %s", otp.Medium)
}
if err := s.otpStore.UpdateOtp(ctx, otpCode, user.UserName); err != nil {
if err := s.otpStore.UpdateOtp(ctx, otpCode, user.ID); err != nil {
return err
}
return nil
}
func (s *Service) SendOtp(ctx context.Context, userName string, sentTo string, otpFor domain.OtpFor, medium domain.OtpMedium, provider domain.SMSProvider) error {
func (s *Service) SendOtp(ctx context.Context, userID int64, sentTo string, otpFor domain.OtpFor, medium domain.OtpMedium, provider domain.SMSProvider) error {
otpCode := helpers.GenerateOTP()
message := fmt.Sprintf("Welcome to Yimaru Online Learning Platform, your OTP is %s please don't share with anyone.", otpCode)
@ -140,7 +137,7 @@ func (s *Service) SendOtp(ctx context.Context, userName string, sentTo string, o
}
otp := domain.Otp{
UserName: userName,
UserID: userID,
SentTo: sentTo,
Medium: medium,
For: otpFor,

View File

@ -25,7 +25,7 @@ func (s *Service) CreateUser(
return s.userStore.CreateUserWithoutOtp(ctx, domain.User{
FirstName: req.FirstName,
LastName: req.LastName,
UserName: req.UserName,
// UserName: req.UserName,
Email: req.Email,
PhoneNumber: req.PhoneNumber,
Password: hashedPassword,
@ -48,7 +48,7 @@ func (s *Service) DeleteUser(ctx context.Context, id int64) error {
func (s *Service) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error) {
// Get all Users
return s.userStore.GetAllUsers(ctx, &filter.Role, &filter.Query.Value, &filter.CreatedBefore.Value, &filter.CreatedAfter.Value, int32(filter.PageSize.Value), int32(filter.Page.Value))
return s.userStore.GetAllUsers(ctx, &filter.Role, &filter.Query, &filter.CreatedBefore.Value, &filter.CreatedAfter.Value, int32(filter.PageSize), int32(filter.Page))
}
func (s *Service) GetUserById(ctx context.Context, id int64) (domain.User, error) {

View File

@ -26,7 +26,7 @@ func (s *Service) SendRegisterCode(ctx context.Context, medium domain.OtpMedium,
}
// send otp based on the medium
return s.SendOtp(ctx, "", sentTo, domain.OtpRegister, medium, provider)
return s.SendOtp(ctx, 0, sentTo, domain.OtpRegister, medium, provider)
}
func (s *Service) RegisterUser(ctx context.Context, registerReq domain.RegisterUserReq) (domain.User, error) {
@ -54,9 +54,9 @@ func (s *Service) RegisterUser(ctx context.Context, registerReq domain.RegisterU
// Prepare the user
userR := domain.User{
FirstName: registerReq.FirstName,
LastName: registerReq.LastName,
UserName: registerReq.UserName,
// FirstName: registerReq.FirstName,
// LastName: registerReq.LastName,
// UserName: registerReq.UserName,
Email: registerReq.Email,
PhoneNumber: registerReq.PhoneNumber,
Password: hashedPassword,
@ -92,9 +92,6 @@ func (s *Service) RegisterUser(ctx context.Context, registerReq domain.RegisterU
}
// 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)
@ -102,5 +99,9 @@ func (s *Service) RegisterUser(ctx context.Context, registerReq domain.RegisterU
return domain.User{}, err
}
if err := s.SendOtp(ctx, user.ID, sentTo, domain.OtpRegister, registerReq.OtpMedium, domain.TwilioSms); err != nil {
return domain.User{}, err
}
return user, nil
}

View File

@ -7,7 +7,7 @@ import (
"time"
)
func (s *Service) SendResetCode(ctx context.Context, userName string, medium domain.OtpMedium, sentTo string, provider domain.SMSProvider) error {
func (s *Service) SendResetCode(ctx context.Context, userID int64, medium domain.OtpMedium, sentTo string, provider domain.SMSProvider) error {
var err error
// check if user exists
@ -22,13 +22,13 @@ func (s *Service) SendResetCode(ctx context.Context, userName string, medium dom
return err
}
return s.SendOtp(ctx, userName, sentTo, domain.OtpReset, medium, provider)
return s.SendOtp(ctx, userID, sentTo, domain.OtpReset, medium, provider)
}
func (s *Service) ResetPassword(ctx context.Context, resetReq domain.ResetPasswordReq) error {
otp, err := s.otpStore.GetOtp(ctx, resetReq.UserName)
otp, err := s.otpStore.GetOtp(ctx, resetReq.UserID)
if err != nil {
return err
}
@ -48,7 +48,7 @@ func (s *Service) ResetPassword(ctx context.Context, resetReq domain.ResetPasswo
return domain.ErrInvalidOtp
}
err = s.userStore.UpdatePassword(ctx, resetReq.Password, resetReq.UserName)
err = s.userStore.UpdatePassword(ctx, resetReq.Password, resetReq.UserID)
if err != nil {
return err
}

View File

@ -14,24 +14,24 @@ func (s *Service) GetUserByEmailPhone(
return s.userStore.GetUserByEmailPhone(ctx, email, phone)
}
func (s *Service) IsUserPending(ctx context.Context, userName string) (bool, error) {
return s.userStore.IsUserPending(ctx, userName)
func (s *Service) IsUserPending(ctx context.Context, userID int64) (bool, error) {
return s.userStore.IsUserPending(ctx, userID)
}
func (s *Service) IsProfileCompleted(ctx context.Context, userId int64) (bool, error) {
return s.userStore.IsProfileCompleted(ctx, userId)
}
func (s *Service) IsUserNameUnique(ctx context.Context, userName string) (bool, error) {
return s.userStore.IsUserNameUnique(ctx, userName)
}
// func (s *Service) IsUserNameUnique(ctx context.Context, userID int64) (bool, error) {
// return s.userStore.IsUserNameUnique(ctx, userID)
// }
func (s *Service) GetUserByUserName(
ctx context.Context,
userName string,
) (domain.User, error) {
return s.userStore.GetUserByUserName(ctx, userName)
}
// func (s *Service) GetUserByUserName(
// ctx context.Context,
// userName string,
// ) (domain.User, error) {
// return s.userStore.GetUserByUserName(ctx, userName)
// }
func (s *Service) SearchUserByNameOrPhone(ctx context.Context, searchString string, role *int64) ([]domain.User, error) {
// Search user
@ -45,29 +45,8 @@ func (s *Service) SearchUserByNameOrPhone(ctx context.Context, searchString stri
}
func (s *Service) UpdateUser(ctx context.Context, req domain.UpdateUserReq) error {
newUser := domain.User{
ID: req.UserID,
FirstName: req.FirstName.Value,
LastName: req.LastName.Value,
KnowledgeLevel: req.KnowledgeLevel.Value,
UserName: req.UserName.Value,
Age: req.Age.Value,
EducationLevel: req.EducationLevel.Value,
Country: req.Country.Value,
Region: req.Region.Value,
Status: domain.UserStatus(req.Status.Value),
NickName: req.NickName.Value,
Occupation: req.Occupation.Value,
LearningGoal: req.LearningGoal.Value,
LanguageGoal: req.LanguageGoal.Value,
LanguageChallange: req.LanguageChallange.Value,
FavoutiteTopic: req.FavoutiteTopic.Value,
PreferredLanguage: req.PreferredLanguage.Value,
ProfilePictureURL: req.ProfilePictureURL.Value,
}
// Update user in the store
return s.userStore.UpdateUser(ctx, newUser)
return s.userStore.UpdateUser(ctx, req)
}
// func (s *Service) UpdateUserSuspend(ctx context.Context, id int64, status bool) error {
@ -87,29 +66,29 @@ func (s *Service) GetUserByID(ctx context.Context, id int64) (domain.User, error
// var query *string
// if filter.Query.Valid {
// q := filter.Query.Value
// q := filter.Query
// query = &q
// }
// var createdBefore *time.Time
// if filter.CreatedBefore.Valid {
// b := filter.CreatedBefore.Value
// b := filter.CreatedBefore
// createdBefore = &b
// }
// var createdAfter *time.Time
// if filter.CreatedAfter.Valid {
// a := filter.CreatedAfter.Value
// a := filter.CreatedAfter
// createdAfter = &a
// }
// var limit int32 = 10
// var offset int32 = 0
// if filter.PageSize.Valid {
// limit = int32(filter.PageSize.Value)
// limit = int32(filter.PageSize)
// }
// if filter.Page.Valid && filter.PageSize.Valid {
// offset = int32(filter.Page.Value * filter.PageSize.Value)
// offset = int32(filter.Page * filter.PageSize)
// }
// return s.userStore.GetAllUsers(ctx, role, query, createdBefore, createdAfter, limit, offset)

View File

@ -163,7 +163,7 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
searchQuery := c.Query("query")
searchString := domain.ValidString{
Value: searchQuery,
Valid: searchQuery != "",
// Valid: searchQuery != "",
}
createdBeforeQuery := c.Query("created_before")
@ -195,15 +195,9 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
// Value: companyID,
// Valid: companyID != 0,
// },
Page: domain.ValidInt{
Value: c.QueryInt("page", 1) - 1,
Valid: true,
},
PageSize: domain.ValidInt{
Value: c.QueryInt("page_size", 10),
Valid: true,
},
Query: searchString,
Page: int64(c.QueryInt("page", 1) - 1),
PageSize: int64(c.QueryInt("page_size", 10)),
Query: searchString.Value,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
}
@ -262,11 +256,11 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
h.mongoLoggerSvc.Info("admins retrieved successfully",
zap.Int("status_code", fiber.StatusOK),
zap.Int("count", len(result)),
zap.Int("page", filter.Page.Value+1),
zap.Int("page", int(filter.Page+1)),
zap.Time("timestamp", time.Now()),
)
return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value+1, int(total))
return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, int(filter.Page+1), int(total))
}
// GetAdminByID godoc
@ -357,14 +351,8 @@ func (h *Handler) UpdateAdmin(c *fiber.Ctx) error {
err = h.userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
UserID: adminID,
FirstName: domain.ValidString{
Value: req.FirstName,
Valid: req.FirstName != "",
},
LastName: domain.ValidString{
Value: req.LastName,
Valid: req.LastName != "",
},
FirstName: req.FirstName,
LastName: req.LastName,
// OrganizationID: orgID,
})
if err != nil {

View File

@ -403,14 +403,8 @@ func (h *Handler) UpdateTransactionApprover(c *fiber.Ctx) error {
updateReq := domain.UpdateUserReq{
UserID: approverID,
FirstName: domain.ValidString{
Value: req.FirstName,
Valid: req.FirstName != "",
},
LastName: domain.ValidString{
Value: req.LastName,
Valid: req.LastName != "",
},
FirstName: req.FirstName,
LastName: req.LastName,
}
err = h.userSvc.UpdateUser(c.Context(), updateReq)
@ -432,4 +426,3 @@ func (h *Handler) UpdateTransactionApprover(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusOK, "Transaction approver updated successfully", nil, nil)
}

View File

@ -77,10 +77,10 @@ func (h *Handler) CheckProfileCompleted(c *fiber.Ctx) error {
// @Failure 400 {object} domain.ErrorResponse
// @Failure 404 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/{tenant_slug}/user [put]
// @Router /api/v1/user [put]
func (h *Handler) UpdateUser(c *fiber.Ctx) error {
// Extract user ID from context
userIDStr, ok := c.Locals("user_id").(string)
userID, ok := c.Locals("user_id").(int64)
if !ok {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user context",
@ -88,13 +88,13 @@ func (h *Handler) UpdateUser(c *fiber.Ctx) error {
})
}
userID, err := strconv.ParseInt(userIDStr, 10, 64)
if err != nil || userID <= 0 {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user ID",
Error: "User ID must be a positive integer",
})
}
// userID, err := strconv.ParseInt(userIDStr, 10, 64)
// if err != nil || userID <= 0 {
// return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
// Message: "Invalid user ID",
// Error: "User ID must be a positive integer",
// })
// }
// Parse request body
var req domain.UpdateUserReq
@ -152,12 +152,11 @@ func (h *Handler) UpdateUser(c *fiber.Ctx) error {
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/{tenant_slug}/user/knowledge-level [put]
func (h *Handler) UpdateUserKnowledgeLevel(c *fiber.Ctx) error {
userIDStr := c.Locals("user_id").(string)
userID, err := strconv.ParseInt(userIDStr, 10, 64)
if err != nil || userID <= 0 {
userID, ok := c.Locals("user_id").(int64)
if !ok {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user ID",
Error: "User ID must be a positive integer",
Message: "Invalid user context",
Error: "User ID not found in request context",
})
}
@ -169,7 +168,7 @@ func (h *Handler) UpdateUserKnowledgeLevel(c *fiber.Ctx) error {
})
}
err = h.userSvc.UpdateUserKnowledgeLevel(c.Context(), userID, req.KnowledgeLevel)
err := h.userSvc.UpdateUserKnowledgeLevel(c.Context(), userID, req.KnowledgeLevel)
if err != nil {
if errors.Is(err, authentication.ErrUserNotFound) {
return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{
@ -302,30 +301,30 @@ func (h *Handler) ResendOtp(c *fiber.Ctx) error {
// @Failure 400 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/user/{user_name}/is-unique [get]
func (h *Handler) CheckUserNameUnique(c *fiber.Ctx) error {
userName := c.Params("user_name")
if userName == "" {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user name",
Error: "user_name path parameter cannot be empty",
})
}
// func (h *Handler) CheckUserNameUnique(c *fiber.Ctx) error {
// userName := c.Params("user_name")
// if userName == "" {
// return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
// Message: "Invalid user name",
// Error: "user_name path parameter cannot be empty",
// })
// }
isUnique, err := h.userSvc.IsUserNameUnique(c.Context(), userName)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
Message: "Failed to check user name uniqueness",
Error: err.Error(),
})
}
// isUnique, err := h.userSvc.IsUserNameUnique(c.Context(), userName)
// if err != nil {
// return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
// Message: "Failed to check user name uniqueness",
// Error: err.Error(),
// })
// }
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: "User name uniqueness checked successfully",
Data: map[string]bool{
"is_unique": isUnique,
},
})
}
// return c.Status(fiber.StatusOK).JSON(domain.Response{
// Message: "User name uniqueness checked successfully",
// Data: map[string]bool{
// "is_unique": isUnique,
// },
// })
// }
// CheckUserPending godoc
// @Summary Check if user status is pending
@ -333,22 +332,28 @@ func (h *Handler) CheckUserNameUnique(c *fiber.Ctx) error {
// @Tags user
// @Accept json
// @Produce json
// @Param user_name path string true "User Name"
// @Param user_id path string true "User ID"
// @Success 200 {object} domain.Response
// @Failure 400 {object} domain.ErrorResponse
// @Failure 404 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/{tenant_slug}/user/{user_name}/is-pending [get]
// @Router /api/v1/user/{user_id}/is-pending [get]
func (h *Handler) CheckUserPending(c *fiber.Ctx) error {
userName := c.Params("user_name")
if userName == "" {
userID, err := strconv.ParseInt(c.Params("user_id"), 10, 64)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user name",
Error: "User name cannot be empty",
Message: "Invalid user ID",
Error: err.Error(),
})
}
if userID == 0 {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid user ID",
Error: "User ID cannot be empty",
})
}
isPending, err := h.userSvc.IsUserPending(c.Context(), userName)
isPending, err := h.userSvc.IsUserPending(c.Context(), userID)
if err != nil {
if errors.Is(err, authentication.ErrUserNotFound) {
return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{
@ -390,7 +395,7 @@ func (h *Handler) GetAllUsers(c *fiber.Ctx) error {
searchQuery := c.Query("query")
searchString := domain.ValidString{
Value: searchQuery,
Valid: searchQuery != "",
// Valid: searchQuery != "",
}
createdBeforeQuery := c.Query("created_before")
@ -417,15 +422,9 @@ func (h *Handler) GetAllUsers(c *fiber.Ctx) error {
filter := domain.UserFilter{
Role: c.Query("role"),
Page: domain.ValidInt{
Value: c.QueryInt("page", 1) - 1,
Valid: true,
},
PageSize: domain.ValidInt{
Value: c.QueryInt("page_size", 10),
Valid: true,
},
Query: searchString,
Page: int64(c.QueryInt("page", 1) - 1),
PageSize: int64(c.QueryInt("page_size", 10)),
Query: searchString.Value,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
}
@ -459,7 +458,7 @@ func (h *Handler) GetAllUsers(c *fiber.Ctx) error {
ID: u.ID,
FirstName: u.FirstName,
LastName: u.LastName,
UserName: u.UserName,
// UserName: u.UserName,
Email: u.Email,
PhoneNumber: u.PhoneNumber,
Role: u.Role,
@ -472,7 +471,7 @@ func (h *Handler) GetAllUsers(c *fiber.Ctx) error {
LearningGoal: u.LearningGoal,
LanguageGoal: u.LanguageGoal,
LanguageChallange: u.LanguageChallange,
FavoutiteTopic: u.FavoutiteTopic,
FavouriteTopic: u.FavouriteTopic,
EmailVerified: u.EmailVerified,
PhoneVerified: u.PhoneVerified,
LastLogin: u.LastLogin,
@ -793,9 +792,9 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error {
}
user := domain.RegisterUserReq{
FirstName: req.FirstName,
LastName: req.LastName,
UserName: req.UserName,
// FirstName: req.FirstName,
// LastName: req.LastName,
// UserName: req.UserName,
Email: req.Email,
PhoneNumber: req.PhoneNumber,
Password: req.Password,
@ -812,7 +811,7 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error {
// LearningGoal: req.LearningGoal,
// LanguageGoal: req.LanguageGoal,
// LanguageChallange: req.LanguageChallange,
// FavoutiteTopic: req.FavoutiteTopic,
// FavouriteTopic: req.FavouriteTopic,
}
medium, err := getMedium(req.Email, req.PhoneNumber)
@ -855,9 +854,9 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error {
func MapRegisterReqToUser(req domain.RegisterUserReq) domain.User {
return domain.User{
FirstName: req.FirstName,
LastName: req.LastName,
UserName: req.UserName,
// FirstName: req.FirstName,
// LastName: req.LastName,
// UserName: req.UserName,
Email: req.Email,
PhoneNumber: req.PhoneNumber,
Password: []byte(req.Password), // or hashed password
@ -873,7 +872,7 @@ func MapRegisterReqToUser(req domain.RegisterUserReq) domain.User {
// LearningGoal: req.LearningGoal,
// LanguageGoal: req.LanguageGoal,
// LanguageChallange: req.LanguageChallange,
// FavoutiteTopic: req.FavoutiteTopic,
// FavouriteTopic: req.FavouriteTopic,
}
}
@ -931,7 +930,7 @@ func (h *Handler) SendResetCode(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, "Email or PhoneNumber must be provided")
}
if err := h.userSvc.SendResetCode(c.Context(), "", medium, sentTo, domain.AfroMessage); err != nil {
if err := h.userSvc.SendResetCode(c.Context(), 0, medium, sentTo, domain.AfroMessage); err != nil {
h.mongoLoggerSvc.Error("Failed to send reset code",
zap.String("medium", string(medium)),
zap.String("sentTo", string(sentTo)),
@ -998,7 +997,7 @@ func (h *Handler) SendTenantResetCode(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, "Email or PhoneNumber must be provided")
}
if err := h.userSvc.SendResetCode(c.Context(), "", medium, sentTo, domain.AfroMessage); err != nil {
if err := h.userSvc.SendResetCode(c.Context(), 0, medium, sentTo, domain.AfroMessage); err != nil {
h.mongoLoggerSvc.Error("Failed to send reset code",
zap.String("medium", string(medium)),
zap.String("sentTo", string(sentTo)),
@ -1013,7 +1012,7 @@ func (h *Handler) SendTenantResetCode(c *fiber.Ctx) error {
}
type ResetPasswordReq struct {
UserName string `json:"user_name" validate:"required" example:"johndoe"`
UserID int64 `json:"user_name" validate:"required" example:"johndoe"`
Password string `json:"password" validate:"required,min=8" example:"newpassword123"`
Otp string `json:"otp" validate:"required" example:"123456"`
}
@ -1072,7 +1071,7 @@ func (h *Handler) ResetPassword(c *fiber.Ctx) error {
// }
resetReq := domain.ResetPasswordReq{
UserName: req.UserName,
UserID: req.UserID,
Password: req.Password,
OtpCode: req.Otp,
}
@ -1139,7 +1138,7 @@ func (h *Handler) ResetTenantPassword(c *fiber.Ctx) error {
// }
resetReq := domain.ResetPasswordReq{
UserName: req.UserName,
UserID: req.UserID,
Password: req.Password,
OtpCode: req.Otp,
}
@ -1210,7 +1209,8 @@ func (h *Handler) GetUserProfile(c *fiber.Ctx) error {
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
// UserName: user.UserName,
Occupation: user.Occupation,
Email: user.Email,
PhoneNumber: user.PhoneNumber,
Role: user.Role,
@ -1299,7 +1299,7 @@ func (h *Handler) AdminProfile(c *fiber.Ctx) error {
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
// UserName: user.UserName,
Email: user.Email,
PhoneNumber: user.PhoneNumber,
Role: user.Role,
@ -1421,7 +1421,7 @@ func (h *Handler) SearchUserByNameOrPhone(c *fiber.Ctx) error {
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
// UserName: user.UserName,
Email: user.Email,
PhoneNumber: user.PhoneNumber,
Role: user.Role,
@ -1503,7 +1503,7 @@ func (h *Handler) GetUserByID(c *fiber.Ctx) error {
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
UserName: user.UserName,
// UserName: user.UserName,
Email: user.Email,
PhoneNumber: user.PhoneNumber,
Role: user.Role,

View File

@ -198,7 +198,7 @@ func (a *App) initAppRoutes() {
groupV1.Get("/users", a.authMiddleware, h.GetAllUsers)
groupV1.Put("/user", a.authMiddleware, h.UpdateUser)
groupV1.Put("/user/knowledge-level", h.UpdateUserKnowledgeLevel)
groupV1.Get("/user/:user_name/is-unique", h.CheckUserNameUnique)
// groupV1.Get("/user/:user_name/is-unique", h.CheckUserNameUnique)
groupV1.Get("/user/:user_name/is-pending", h.CheckUserPending)
groupV1.Post("/user/resetPassword", h.ResetPassword)
groupV1.Post("/user/sendResetCode", h.SendResetCode)