feat: add localization to expection messages

This commit is contained in:
Abdalhamid Alhamad
2025-01-14 12:39:19 +03:00
parent 5aa3d3774d
commit 6d2d2b558a
6 changed files with 200 additions and 21 deletions

View File

@ -65,7 +65,7 @@ export class AuthService {
this.logger.error( this.logger.error(
`User with phone number ${verifyUserDto.countryCode + verifyUserDto.phoneNumber} already verified`, `User with phone number ${verifyUserDto.countryCode + verifyUserDto.phoneNumber} already verified`,
); );
throw new BadRequestException('USERS.PHONE_ALREADY_VERIFIED'); throw new BadRequestException('USER.PHONE_ALREADY_VERIFIED');
} }
const isOtpValid = await this.otpService.verifyOtp({ const isOtpValid = await this.otpService.verifyOtp({
@ -79,7 +79,7 @@ export class AuthService {
this.logger.error( this.logger.error(
`Invalid OTP for user with phone number ${verifyUserDto.countryCode + verifyUserDto.phoneNumber}`, `Invalid OTP for user with phone number ${verifyUserDto.countryCode + verifyUserDto.phoneNumber}`,
); );
throw new BadRequestException('USERS.INVALID_OTP'); throw new BadRequestException('OTP.INVALID_OTP');
} }
if (user.isPhoneVerified) { if (user.isPhoneVerified) {
@ -108,14 +108,14 @@ export class AuthService {
if (user.email) { if (user.email) {
this.logger.error(`Email already set for user with id ${userId}`); this.logger.error(`Email already set for user with id ${userId}`);
throw new BadRequestException('USERS.EMAIL_ALREADY_SET'); throw new BadRequestException('USER.EMAIL_ALREADY_SET');
} }
const existingUser = await this.userService.findUser({ email }); const existingUser = await this.userService.findUser({ email });
if (existingUser) { if (existingUser) {
this.logger.error(`Email ${email} already taken`); this.logger.error(`Email ${email} already taken`);
throw new BadRequestException('USERS.EMAIL_ALREADY_TAKEN'); throw new BadRequestException('USER.EMAIL_ALREADY_TAKEN');
} }
return this.userService.setEmail(userId, email); return this.userService.setEmail(userId, email);
@ -127,7 +127,7 @@ export class AuthService {
if (user.password) { if (user.password) {
this.logger.error(`Passcode already set for user with id ${userId}`); this.logger.error(`Passcode already set for user with id ${userId}`);
throw new BadRequestException('USERS.PASSCODE_ALREADY_SET'); throw new BadRequestException('AUTH.PASSCODE_ALREADY_SET');
} }
const salt = bcrypt.genSaltSync(SALT_ROUNDS); const salt = bcrypt.genSaltSync(SALT_ROUNDS);
const hashedPasscode = bcrypt.hashSync(passcode, salt); const hashedPasscode = bcrypt.hashSync(passcode, salt);
@ -141,14 +141,14 @@ export class AuthService {
if (user.phoneNumber || user.countryCode) { if (user.phoneNumber || user.countryCode) {
this.logger.error(`Phone number already set for user with id ${userId}`); this.logger.error(`Phone number already set for user with id ${userId}`);
throw new BadRequestException('USERS.PHONE_NUMBER_ALREADY_SET'); throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_SET');
} }
const existingUser = await this.userService.findUser({ phoneNumber, countryCode }); const existingUser = await this.userService.findUser({ phoneNumber, countryCode });
if (existingUser) { if (existingUser) {
this.logger.error(`Phone number ${countryCode + phoneNumber} already taken`); this.logger.error(`Phone number ${countryCode + phoneNumber} already taken`);
throw new BadRequestException('USERS.PHONE_NUMBER_ALREADY_TAKEN'); throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_TAKEN');
} }
await this.userService.setPhoneNumber(userId, phoneNumber, countryCode); await this.userService.setPhoneNumber(userId, phoneNumber, countryCode);
@ -171,7 +171,7 @@ export class AuthService {
if (!isOtpValid) { if (!isOtpValid) {
this.logger.error(`Invalid OTP for user with id ${userId}`); this.logger.error(`Invalid OTP for user with id ${userId}`);
throw new BadRequestException('USERS.INVALID_OTP'); throw new BadRequestException('OTP.INVALID_OTP');
} }
return this.userService.verifyPhoneNumber(userId); return this.userService.verifyPhoneNumber(userId);
@ -220,7 +220,7 @@ export class AuthService {
if (!user.isProfileCompleted) { if (!user.isProfileCompleted) {
this.logger.error(`Profile not completed for user with email ${email}`); this.logger.error(`Profile not completed for user with email ${email}`);
throw new BadRequestException('USERS.PROFILE_NOT_COMPLETED'); throw new BadRequestException('USER.PROFILE_NOT_COMPLETED');
} }
return this.otpService.generateAndSendOtp({ return this.otpService.generateAndSendOtp({
@ -236,7 +236,7 @@ export class AuthService {
const user = await this.userService.findUserOrThrow({ email }); const user = await this.userService.findUserOrThrow({ email });
if (!user.isProfileCompleted) { if (!user.isProfileCompleted) {
this.logger.error(`Profile not completed for user with email ${email}`); this.logger.error(`Profile not completed for user with email ${email}`);
throw new BadRequestException('USERS.PROFILE_NOT_COMPLETED'); throw new BadRequestException('USER.PROFILE_NOT_COMPLETED');
} }
const isOtpValid = await this.otpService.verifyOtp({ const isOtpValid = await this.otpService.verifyOtp({
userId: user.id, userId: user.id,
@ -247,7 +247,7 @@ export class AuthService {
if (!isOtpValid) { if (!isOtpValid) {
this.logger.error(`Invalid OTP for user with email ${email}`); this.logger.error(`Invalid OTP for user with email ${email}`);
throw new BadRequestException('USERS.INVALID_OTP'); throw new BadRequestException('OTP.INVALID_OTP');
} }
this.validatePassword(password, confirmPassword, user); this.validatePassword(password, confirmPassword, user);

View File

@ -82,6 +82,8 @@ export class CustomerService {
} }
if (profilePicture.createdById && profilePicture.createdById !== userId) { if (profilePicture.createdById && profilePicture.createdById !== userId) {
this.logger.error(`Profile picture ${profilePictureId} does not belong to user ${userId}`);
throw new BadRequestException('DOCUMENT.NOT_CREATED_BY_USER');
} }
} }
} }

View File

@ -133,7 +133,7 @@ export class GiftsService {
if (image.createdById && image.createdById !== userId) { if (image.createdById && image.createdById !== userId) {
this.logger.error(`Gift image ${imageId} does not belong to user ${userId}`); this.logger.error(`Gift image ${imageId} does not belong to user ${userId}`);
throw new BadRequestException('DOCUMENT.NOT_BELONG_TO_USER'); throw new BadRequestException('DOCUMENT.NOT_CREATED_BY_USER');
} }
} }
} }

View File

@ -1,5 +1,94 @@
{ {
"DOCUMENTS": { "AUTH": {
"TYPE_NOT_SUPPORTED": "نوع الملف غير مدعوم" "BIOMETRIC_ALREADY_ENABLED": "المصادقة البيومترية مفعلة بالفعل على حسابك.",
"DEVICE_NOT_FOUND": "الجهاز المحدد غير موجود، يرجى المحاولة مرة أخرى.",
"BIOMETRIC_ALREADY_DISABLED": "المصادقة البيومترية معطلة بالفعل لحسابك.",
"APPLE_LOGIN_NOT_IMPLEMENTED": "تكامل تسجيل الدخول باستخدام Apple غير متوفر حاليًا. يرجى تجربة طريقة تسجيل دخول بديلة.",
"INVALID_REFRESH_TOKEN": "رمز التحديث المقدم غير صالح. يرجى تسجيل الدخول مرة أخرى.",
"INVALID_CREDENTIALS": "اسم المستخدم أو كلمة المرور التي أدخلتها غير صحيحة. يرجى المحاولة مرة أخرى.",
"BIOMETRIC_NOT_ENABLED": "المصادقة البيومترية لم يتم تفعيلها على حسابك. يرجى تفعيلها للمتابعة.",
"INVALID_BIOMETRIC": "البيانات البيومترية المقدمة غير صالحة. يرجى المحاولة مرة أخرى أو إعادة إعداد المصادقة البيومترية.",
"PASSWORD_MISMATCH": "كلمات المرور التي أدخلتها غير متطابقة. يرجى إدخال كلمات المرور مرة أخرى.",
"INVALID_PASSCODE": "رمز المرور الذي أدخلته غير صحيح. يرجى المحاولة مرة أخرى.",
"PASSCODE_ALREADY_SET": "تم تعيين رمز المرور بالفعل."
},
"USER": {
"PHONE_ALREADY_VERIFIED": "تم التحقق من رقم الهاتف بالفعل.",
"EMAIL_ALREADY_SET": "تم تعيين عنوان البريد الإلكتروني بالفعل.",
"EMAIL_ALREADY_TAKEN": "عنوان البريد الإلكتروني مستخدم بالفعل. يرجى تجربة عنوان بريد إلكتروني آخر.",
"PHONE_NUMBER_ALREADY_SET": "تم تعيين رقم الهاتف بالفعل.",
"PHONE NUMBER ALREADY TAKEN": "رقم الهاتف مستخدم بالفعل. يرجى تجربة رقم هاتف آخر.",
"PROFILE_NOT_COMPLETED": "ملفك الشخصي غير مكتمل. يرجى إكمال الملف الشخصي للمتابعة.",
"ALREADY_EXISTS": "المستخدم موجود بالفعل.",
"NOT_FOUND": "لم يتم العثور على المستخدم.",
"PHONE_NUMBER_ALREADY_EXISTS": "رقم الهاتف موجود بالفعل.",
"JUNIOR_UPGRADE_NOT_SUPPORTED_YET": "ترقية الحساب من حساب طفل إلى حساب ولي أمر غير مدعومة حاليًا."
},
"ALLOWANCE": {
"START_DATE_BEFORE_TODAY": "لا يمكن أن يكون تاريخ البدء قبل اليوم.",
"START_DATE_AFTER_END_DATE": "لا يمكن أن يكون تاريخ البدء بعد تاريخ النهاية.",
"NOT_FOUND": "لم يتم العثور على المصروف.",
"DOES_NOT_BELONG_TO_JUNIOR": "المصروف لا يخص الطفل."
},
"ALLOWANCE_CHANGE_REQUEST": {
"SAME_AMOUNT": "المبلغ الجديد هو نفسه المبلغ الحالي.",
"SAME_AMOUNT_PENDING": "هناك طلب معلق بنفس المبلغ.",
"NOT_FOUND": "لم يتم العثور على طلب تغيير المصروف.",
"ALREADY_APPROVED": "تمت الموافقة على طلب تغيير المصروف بالفعل.",
"ALREADY_REJECTED": "تم رفض طلب تغيير المصروف بالفعل."
},
"CUSTOMER": {
"NOT_FOUND": "لم يتم العثور على العميل."
},
"GIFT": {
"NOT_FOUND": "لم يتم العثور على الهدية.",
"ALREADY_REDEEMED": "تم استرداد الهدية بالفعل.",
"NOT_REDEEMED": "لم يتم استرداد الهدية بعد.",
"ALREADY_REPLIED": "تم الرد على الهدية بالفعل."
},
"JUNIOR": {
"DOES_NOT_BELONG_TO_GUARDIAN": "الطفل لا ينتمي إلى ولي الأمر.",
"NOT_FOUND": "لم يتم العثور على الطفل.",
"CIVIL_ID_REQUIRED": "مطلوب بطاقة الهوية المدنية.",
"CIVIL_ID_NOT_CREATED_BY_GUARDIAN": "تم تحميل بطاقة الهوية المدنية من قبل شخص آخر غير ولي الأمر.",
"CIVIL_ID_ALREADY_EXISTS": "بطاقة الهوية المدنية مستخدمة بالفعل من قبل طفل آخر."
},
"MONEY_REQUEST": {
"START_DATE_IN_THE_PAST": "لا يمكن أن يكون تاريخ البدء في الماضي.",
"END_DATE_IN_THE_PAST": "لا يمكن أن يكون تاريخ النهاية في الماضي.",
"END_DATE_BEFORE_START_DATE": "لا يمكن أن يكون تاريخ النهاية قبل تاريخ البدء.",
"NOT_FOUND": "لم يتم العثور على طلب المال.",
"ENDED": "تم انتهاء طلب المال.",
"ALREADY_REVIEWED": "تمت مراجعة طلب المال بالفعل."
},
"GOAL": {
"DUE_DATE_MUST_BE_IN_THE_FUTURE": "يجب أن يكون تاريخ النهاية في المستقبل.",
"NOT_FOUND": "لم يتم العثور على الهدف التوفيري.",
"FUND_EXCEEDS_TOTAL_AMOUNT": "المبلغ الممول يتجاوز إجمالي مبلغ الهدف التوفيري."
},
"TASK": {
"DUE_DATE_BEFORE_START_DATE": "لا يمكن أن يكون تاريخ النهاية قبل تاريخ البدء.",
"DUE_DATE_IN_PAST": "لا يمكن أن يكون تاريخ النهاية في الماضي.",
"NOT_FOUND": "لم يتم العثور على المهمة.",
"ALREADY_COMPLETED": "تم إكمال المهمة بالفعل.",
"PROOF_REQUIRED": "يتطلب تقديم إثبات لهذه المهمة.",
"NO_SUBMISSION": "لم يتم العثور على أي تقديم لهذه المهمة.",
"SUBMISSION_ALREADY_REVIEWED": "تمت مراجعة التقديم بالفعل."
},
"DOCUMENT": {
"NOT_FOUND": "لم يتم العثور على الملف.",
"TYPE_NOT_SUPPORTED": "نوع الملف غير مدعوم.",
"NOT_CREATED_BY_USER": "لم يتم إنشاء الملف من قبل المستخدم."
},
"OTP": {
"INVALID_OTP": "رمز التحقق الذي أدخلته غير صالح. يرجى المحاولة مرة أخرى."
} }
} }

View File

@ -1,5 +1,93 @@
{ {
"DOCUMENTS": { "AUTH": {
"TYPE_NOT_SUPPORTED": "Document type is not supported" "BIOMETRIC_ALREADY_ENABLED": "Biometric authentication is already active on your account.",
"DEVICE_NOT_FOUND": "The specified device is not found, please try again.",
"BIOMETRIC_ALREADY_DISABLED": "Biometric authentication is already disabled for your account.",
"APPLE_LOGIN_NOT_IMPLEMENTED": "Apple login integration is currently unavailable. Please try an alternative login method.",
"INVALID_REFRESH_TOKEN": "The refresh token provided is invalid. Please log in again.",
"INVALID_CREDENTIALS": "The username or password you entered is incorrect. Please try again.",
"BIOMETRIC_NOT_ENABLED": "Biometric authentication has not been activated for your account. Please enable it to proceed.",
"INVALID_BIOMETRIC": "The biometric data provided is invalid. Please try again or reconfigure your biometric settings.",
"PASSWORD_MISMATCH": "The passwords you entered do not match. Please re-enter the passwords.",
"INVALID_PASSCODE": "The passcode you entered is incorrect. Please try again.",
"PASSCODE_ALREADY_SET": "The pass code has already been set."
},
"USER": {
"PHONE_ALREADY_VERIFIED": "The phone number has already been verified.",
"EMAIL_ALREADY_SET": "The email address has already been set.",
"EMAIL_ALREADY_TAKEN": "The email address is already in use. Please try another email address.",
"PHONE_NUMBER_ALREADY_SET": "The phone number has already been set.",
"PHONE NUMBER ALREADY TAKEN": "The phone number is already in use. Please try another phone number.",
"PROFILE_NOT_COMPLETED": "Your profile is not yet complete. Please complete your profile to proceed.",
"ALREADY_EXISTS": "The user already exists.",
"NOT_FOUND": "The user was not found.",
"PHONE_NUMBER_ALREADY_EXISTS": "The phone number already exists.",
"JUNIOR_UPGRADE_NOT_SUPPORTED_YET": "Upgrading account from junior to guardian is not yet supported."
},
"ALLOWANCE": {
"START_DATE_BEFORE_TODAY": "The start date cannot be before today.",
"START_DATE_AFTER_END_DATE": "The start date cannot be after the end date.",
"NOT_FOUND": "The allowance was not found.",
"DOES_NOT_BELONG_TO_JUNIOR": "The allowance does not belong to the junior."
},
"ALLOWANCE_CHANGE_REQUEST": {
"SAME_AMOUNT": "The new amount is the same as the current amount.",
"SAME_AMOUNT_PENDING": "There is already a pending request with the same amount.",
"NOT_FOUND": "The allowance change request was not found.",
"ALREADY_APPROVED": "The allowance change request has already been approved.",
"ALREADY_REJECTED": "The allowance change request has already been rejected."
},
"CUSTOMER": {
"NOT_FOUND": "The customer was not found."
},
"GIFT": {
"NOT_FOUND": "The gift was not found.",
"ALREADY_REDEEMED": "The gift has already been redeemed.",
"NOT_REDEEMED": "The gift has not been redeemed yet.",
"ALREADY_REPLIED": "The gift has already been replied to."
},
"JUNIOR": {
"DOES_NOT_BELONG_TO_GUARDIAN": "The junior does not belong to the guardian.",
"NOT_FOUND": "The junior was not found.",
"CIVIL_ID_REQUIRED": "Civil ID is required.",
"CIVIL_ID_NOT_CREATED_BY_GUARDIAN": "The civil ID document was not uploaded by the guardian.",
"CIVIL_ID_ALREADY_EXISTS": "The civil ID is already used by another junior."
},
"MONEY_REQUEST": {
"START_DATE_IN_THE_PAST": "The start date cannot be in the past.",
"END_DATE_IN_THE_PAST": "The end date cannot be in the past.",
"END_DATE_BEFORE_START_DATE": "The end date cannot be before the start date.",
"NOT_FOUND": "The money request was not found.",
"ENDED": "The money request has ended.",
"ALREADY_REVIEWED": "The money request has already been reviewed."
},
"GOAL": {
"DUE_DATE_MUST_BE_IN_THE_FUTURE": "The due date must be in the future.",
"NOT_FOUND": "The goal was not found.",
"FUND_EXCEEDS_TOTAL_AMOUNT": "The fund amount exceeds the total amount of the goal."
},
"TASK": {
"DUE_DATE_BEFORE_START_DATE": "The due date cannot be before the start date.",
"DUE_DATE_IN_PAST": "The due date cannot be in the past.",
"NOT_FOUND": "The task was not found.",
"ALREADY_COMPLETED": "The task has already been completed.",
"PROOF_REQUIRED": "Proof is required for this task.",
"NO_SUBMISSION": "No submission found for this task.",
"SUBMISSION_ALREADY_REVIEWED": "The submission has already been reviewed."
},
"DOCUMENT": {
"NOT_FOUND": "The document was not found.",
"TYPE_NOT_SUPPORTED": "Document type is not supported.",
"NOT_CREATED_BY_USER": "The document was not created by the user."
},
"OTP": {
"INVALID_OTP": "The OTP you entered is invalid. Please try again."
} }
} }

View File

@ -26,7 +26,7 @@ export class UserService {
if (!user) { if (!user) {
this.logger.error(`User with not found with where clause ${JSON.stringify(where)}`); this.logger.error(`User with not found with where clause ${JSON.stringify(where)}`);
throw new BadRequestException('USERS.NOT_FOUND'); throw new BadRequestException('USER.NOT_FOUND');
} }
this.logger.log(`User with where clause ${JSON.stringify(where)} found successfully`); this.logger.log(`User with where clause ${JSON.stringify(where)} found successfully`);
@ -43,12 +43,12 @@ export class UserService {
} }
if (user && user.roles.includes(Roles.GUARDIAN) && user.isProfileCompleted) { if (user && user.roles.includes(Roles.GUARDIAN) && user.isProfileCompleted) {
this.logger.error(`User with phone number ${phoneNumber} already exists`); this.logger.error(`User with phone number ${phoneNumber} already exists`);
throw new BadRequestException('USERS.PHONE_NUMBER_ALREADY_EXISTS'); throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_EXISTS');
} }
if (user && user.roles.includes(Roles.JUNIOR)) { if (user && user.roles.includes(Roles.JUNIOR)) {
this.logger.error(`User with phone number ${phoneNumber} is an already registered junior`); this.logger.error(`User with phone number ${phoneNumber} is an already registered junior`);
throw new BadRequestException('USERS.JUNIOR_UPGRADE_NOT_SUPPORTED_YET'); throw new BadRequestException('USER.JUNIOR_UPGRADE_NOT_SUPPORTED_YET');
//TODO add role Guardian to the existing user and send OTP //TODO add role Guardian to the existing user and send OTP
} }