🔧 chore(account): update account module structure and email queue processing

- Enhanced account management with new validation and Swagger documentation.
- Updated Prisma schemas and migrations for the account and profile.
- Improved email handling mechanisms in the email queue system with new worker functionality.
- Adjusted Docker configurations and package dependencies for better integration.
This commit is contained in:
2026-04-03 00:54:46 +06:00
parent 81f9801487
commit 3f0ead4265
18 changed files with 285 additions and 98 deletions
@@ -18,7 +18,7 @@ const verify_account_using_otp = catchAsync(async (req, res) => {
manageResponse(res, {
statusCode: 200,
success: true,
message: "Otp verification successfull",
message: "Otp verification successful",
data: result,
});
});
@@ -28,7 +28,7 @@ const verify_account_using_link = catchAsync(async (req, res) => {
manageResponse(res, {
statusCode: 200,
success: true,
message: "Account verification successfull",
message: "Account verification successful",
data: result,
});
});
@@ -83,9 +83,9 @@ const resend_otp_and_verification_link = catchAsync(async (req, res) => {
});
});
const forget_password_genereate_reset_token = catchAsync(async (req, res) => {
const forget_password_generate_reset_token = catchAsync(async (req, res) => {
const result =
await account_services.forget_password_genereate_reset_token_from_db(req);
await account_services.forget_password_generate_reset_token_from_db(req);
manageResponse(res, {
statusCode: 200,
success: true,
@@ -111,6 +111,6 @@ export const account_controller = {
verify_account_using_otp,
resend_otp_and_verification_link,
verify_account_using_link,
forget_password_genereate_reset_token,
forget_password_generate_reset_token,
reset_password_using_token
};
+1 -1
View File
@@ -45,7 +45,7 @@ accountRouter.put(
accountRouter.put(
"/forget-password",
RequestValidator(account_validation.resend_otp),
account_controller.forget_password_genereate_reset_token,
account_controller.forget_password_generate_reset_token,
);
accountRouter.put(
"/reset-password",
+22 -21
View File
@@ -2,14 +2,22 @@ import bcrypt from "bcrypt";
import { Request } from "express";
import { configs } from "../../configs";
import { prisma } from "../../lib/prisma";
import { emailQueue } from "../../queues/email/email.queue";
import { AppError } from "../../utils/app_error";
import { jwtHelpers } from "../../utils/JWT";
import { otpGenerator } from "../../utils/otpGenerator";
import sendMail from "../../utils/mail_sender";
import { otpGenerator } from "../../utils/otpGenerator";
const create_account_into_db = async (req: Request) => {
const payload = req?.body;
// check account exist or not
const existingAccount = await prisma.account.findUnique({
where: { email: payload.email },
});
if (existingAccount) {
throw new AppError("Email already exists", 403);
}
// hash password
const hashPassword = bcrypt.hashSync(payload.password, 10);
@@ -24,7 +32,7 @@ const create_account_into_db = async (req: Request) => {
const profile = await tx.profile.create({
data: {
fullName: payload.fullName,
shopName: payload.shopName,
accountId: account.id,
},
});
@@ -56,22 +64,14 @@ const create_account_into_db = async (req: Request) => {
lastOtpSendingTime: new Date(),
},
});
await sendMail({
to: payload.email as string,
subject: "welcome to - Please verify your account",
htmlBody: `
<p><strong>OTP</strong> ${newOtp}</p>
<small>Otp will be expire in 5 minutes</small>
<br/> <br/>
<p>Or you can use Verification link </p>
<p>${verificationLink}</p>
`,
textBody: "You can use otp or direct link",
name: payload.fullName,
});
await emailQueue.add("email-queue", {
name: payload.shopName,
otp: newOtp,
verificationLink: verificationLink,
subject: "Welcome to Quick Launch - Verification OTP",
email: payload.email,
textBody: "You can use otp or verification link for verifying your account"
})
return result;
};
@@ -96,7 +96,7 @@ const verify_account_using_otp_into_db = async (req: Request) => {
const OTP_EXPIRY_TIME = 5 * 60 * 1000; // 5 minutes in ms
const isOtpExpired = account.lastOtpSendingTime
? new Date().getTime() - new Date(account.lastOtpSendingTime).getTime() >
OTP_EXPIRY_TIME
OTP_EXPIRY_TIME
: true;
if (isOtpExpired) {
@@ -316,7 +316,7 @@ const resend_otp_and_verification_link_from_db = async (req: Request) => {
});
};
const forget_password_genereate_reset_token_from_db = async (req: Request) => {
const forget_password_generate_reset_token_from_db = async (req: Request) => {
const email = req?.body?.email as string;
const account = await prisma.account.findUnique({
where: {
@@ -389,6 +389,7 @@ const reset_password_using_token_into_db = async (req: Request) => {
// infuter user alart for changing password
return "";
};
export const account_services = {
create_account_into_db,
login_user_into_db,
@@ -397,6 +398,6 @@ export const account_services = {
verify_account_using_otp_into_db,
resend_otp_and_verification_link_from_db,
verify_account_using_link_into_db,
forget_password_genereate_reset_token_from_db,
forget_password_generate_reset_token_from_db,
reset_password_using_token_into_db
};
+1 -1
View File
@@ -11,7 +11,7 @@ export const accountSwaggerDocs = {
example: JSON.stringify({
email: "user@gmail.com",
password: "password",
fullName: "User",
shopName: "User",
}),
},
},
@@ -3,7 +3,7 @@ import z from "zod";
const sign_up = z.object({
email: z.string("Email is required."),
password: z.string("Password is required."),
fullName: z.string("Full name is required."),
shopName: z.string("Full name is required."),
});
const sing_in = z.object({
@@ -12,19 +12,19 @@ const sing_in = z.object({
});
const change_password = z.object({
oldPassword: z.string("Old Password is requied"),
oldPassword: z.string("Old Password is required"),
newPassword: z.string("New Password is required"),
});
const verify_otp = z.object({
email: z.string("Email is requied"),
email: z.string("Email is required"),
otp: z.string("OTP is required"),
});
const verify_link = z.object({
token: z.string("Token is required "),
});
const resend_otp = z.object({
email: z.string("Email is requied"),
email: z.string("Email is required"),
});
const reset_pass = z.object({
token: z.string("Token is required"),