diff --git a/src/allowance/controllers/allowance-change-request.controller.ts b/src/allowance/controllers/allowance-change-request.controller.ts index e2ed0ef..88100b4 100644 --- a/src/allowance/controllers/allowance-change-request.controller.ts +++ b/src/allowance/controllers/allowance-change-request.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { PageOptionsRequestDto } from '~/core/dtos'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; @@ -15,6 +15,7 @@ import { AllowanceChangeRequestsService } from '../services'; @Controller('allowance-change-requests') @ApiTags('Allowance Change Requests') @ApiBearerAuth() +@ApiLangRequestHeader() export class AllowanceChangeRequestController { constructor(private readonly allowanceChangeRequestsService: AllowanceChangeRequestsService) {} diff --git a/src/allowance/controllers/allowances.controller.ts b/src/allowance/controllers/allowances.controller.ts index f028fff..44961e9 100644 --- a/src/allowance/controllers/allowances.controller.ts +++ b/src/allowance/controllers/allowances.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { PageOptionsRequestDto } from '~/core/dtos'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; @@ -15,6 +15,7 @@ import { AllowancesService } from '../services'; @Controller('allowances') @ApiTags('Allowances') @ApiBearerAuth() +@ApiLangRequestHeader() export class AllowancesController { constructor(private readonly allowancesService: AllowancesService) {} diff --git a/src/auth/controllers/auth.controller.ts b/src/auth/controllers/auth.controller.ts index 9a75012..441ea09 100644 --- a/src/auth/controllers/auth.controller.ts +++ b/src/auth/controllers/auth.controller.ts @@ -4,6 +4,7 @@ import { Request } from 'express'; import { DEVICE_ID_HEADER } from '~/common/constants'; import { AuthenticatedUser, Public } from '~/common/decorators'; import { AccessTokenGuard } from '~/common/guards'; +import { ApiLangRequestHeader } from '~/core/decorators'; import { ResponseFactory } from '~/core/utils'; import { CreateUnverifiedUserRequestDto, @@ -27,6 +28,7 @@ import { AuthService } from '../services'; @Controller('auth') @ApiTags('Auth') @ApiBearerAuth() +@ApiLangRequestHeader() export class AuthController { constructor(private readonly authService: AuthService) {} @Post('register/otp') diff --git a/src/customer/controllers/customer.controller.ts b/src/customer/controllers/customer.controller.ts index abddf4c..ce26a7f 100644 --- a/src/customer/controllers/customer.controller.ts +++ b/src/customer/controllers/customer.controller.ts @@ -4,7 +4,7 @@ import { IJwtPayload } from '~/auth/interfaces'; import { DEVICE_ID_HEADER } from '~/common/constants'; import { AuthenticatedUser } from '~/common/decorators'; import { AccessTokenGuard } from '~/common/guards'; -import { ApiDataResponse } from '~/core/decorators'; +import { ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { ResponseFactory } from '~/core/utils'; import { UpdateCustomerRequestDto, UpdateNotificationsSettingsRequestDto } from '../dtos/request'; import { CustomerResponseDto, NotificationSettingsResponseDto } from '../dtos/response'; @@ -13,6 +13,7 @@ import { CustomerService } from '../services'; @Controller('customers') @ApiTags('Customers') @ApiBearerAuth() +@ApiLangRequestHeader() export class CustomerController { constructor(private readonly customerService: CustomerService) {} diff --git a/src/customer/dtos/request/update-notifications-settings.request.dto.ts b/src/customer/dtos/request/update-notifications-settings.request.dto.ts index e54ffb6..47c94de 100644 --- a/src/customer/dtos/request/update-notifications-settings.request.dto.ts +++ b/src/customer/dtos/request/update-notifications-settings.request.dto.ts @@ -18,7 +18,7 @@ export class UpdateNotificationsSettingsRequestDto { isSmsEnabled!: boolean; @ApiPropertyOptional() - @IsString({ message: i18n('validation.isString', { path: 'general', property: 'customer.fcmToken' }) }) + @IsString({ message: i18n('validation.isString', { path: 'general', property: 'auth.fcmToken' }) }) @ValidateIf((o) => o.isPushEnabled) fcmToken?: string; } diff --git a/src/document/controllers/document.controller.ts b/src/document/controllers/document.controller.ts index e884113..7b3eed1 100644 --- a/src/document/controllers/document.controller.ts +++ b/src/document/controllers/document.controller.ts @@ -5,6 +5,7 @@ import { memoryStorage } from 'multer'; import { IJwtPayload } from '~/auth/interfaces'; import { AuthenticatedUser } from '~/common/decorators'; import { AccessTokenGuard } from '~/common/guards'; +import { ApiLangRequestHeader } from '~/core/decorators'; import { ResponseFactory } from '~/core/utils'; import { UploadDocumentRequestDto } from '../dtos/request'; import { DocumentMetaResponseDto } from '../dtos/response'; @@ -14,6 +15,7 @@ import { DocumentService } from '../services'; @ApiTags('Document') @ApiBearerAuth() @UseGuards(AccessTokenGuard) +@ApiLangRequestHeader() export class DocumentController { constructor(private readonly documentService: DocumentService) {} diff --git a/src/gift/controllers/gifts.controller.ts b/src/gift/controllers/gifts.controller.ts index 2926a8b..6d8f2e6 100644 --- a/src/gift/controllers/gifts.controller.ts +++ b/src/gift/controllers/gifts.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { AccessTokenGuard, RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { ResponseFactory } from '~/core/utils'; import { CreateGiftRequestDto, GiftFiltersRequestDto, GiftReplyRequestDto } from '../dtos/request'; import { GiftDetailsResponseDto, GiftListResponseDto } from '../dtos/response'; @@ -13,6 +13,7 @@ import { GiftsService } from '../services'; @Controller('gift') @ApiTags('Gifts') @ApiBearerAuth() +@ApiLangRequestHeader() export class GiftsController { constructor(private readonly giftsService: GiftsService) {} diff --git a/src/i18n/ar/general.json b/src/i18n/ar/general.json index 64f02d1..e77f46b 100644 --- a/src/i18n/ar/general.json +++ b/src/i18n/ar/general.json @@ -4,6 +4,102 @@ "paginationSize": "حجم الصفحة", "document": { "documentType": "نوع الملف" + }, + "auth": { + "countryCode": "رمز الدولة", + "phoneNumber": "رقم الهاتف", + "deviceId": "معرّف الجهاز", + "publicKey": "المفتاح العام", + "email": "البريد الإلكتروني", + "password": "كلمة المرور", + "confirmPassword": "تأكيد كلمة المرور", + "otp": "رمز التحقق", + "grantType": "نوع الإذن", + "signature": "التوقيع", + "googleToken": "رمز جوجل", + "fcmToken": "رمز FCM", + "refreshToken": "رمز التحديث", + "qrToken": "رمز QR", + "passcode": "رمز المرور" + }, + + "customer": { + "firstName": "الاسم الأول", + "lastName": "اسم العائلة", + "countryOfResidence": "بلد الإقامة", + "dateOfBirth": "تاريخ الميلاد", + "profilePictureId": "معرّف صورة الملف الشخصي", + "isEmailEnabled": "هل البريد الإلكتروني مفعّل", + "isSmsEnabled": "هل الرسائل النصية مفعّلة", + "isPushEnabled": "هل الإشعارات مفعّلة" + }, + + "junior": { + "relationship": "العلاقة", + "civilIdFrontId": "الوجه الأمامي لبطاقة الهوية المدنية", + "civilIdBackId": "الوجه الخلفي لبطاقة الهوية المدنية", + "color": "اللون", + "avatarId": "معرّف الصورة الرمزية" + }, + + "moneyRequest": { + "requestedAmount": "المبلغ المطلوب", + "message": "الرسالة", + "frequency": "التكرار", + "startDate": "تاريخ البدء", + "endDate": "تاريخ النهاية", + "status": "الحالة" + }, + + "goal": { + "category": { + "name": "الاسم" + }, + "name": "الاسم", + "description": "الوصف", + "dueDate": "تاريخ النهاية", + "targetAmount": "المبلغ المستهدف", + "categoryIds": "معرّفات التصنيفات", + "imageId": "معرّف الصورة", + "fundAmount": "المبلغ الممول" + }, + + "task": { + "title": "العنوان", + "description": "الوصف", + "startDate": "تاريخ البدء", + "dueDate": "تاريخ النهاية", + "rewardAmount": "قيمة المكافأة", + "frequency": "التكرار", + "isProofRequired": "هل يتطلب إثبات", + "imageId": "معرّف الصورة", + "juniorId": "معرّف الطفل", + "status": "الحالة" + }, + + "gift": { + "name": "الاسم", + "description": "الوصف", + "color": "اللون", + "amount": "المبلغ", + "imageId": "معرّف الصورة", + "recipientId": "معرّف المستلم", + "status": "الحالة" + }, + + "allowance": { + "name": "الاسم", + "amount": "المبلغ", + "type": "النوع", + "startDate": "تاريخ البدء", + "endDate": "تاريخ النهاية", + "numberOfTransactions": "عدد المعاملات", + "juniorId": "معرّف الطفل" + }, + "allowanceChangeRequest": { + "reason": "السبب", + "allowanceId": "معرّف المصروف", + "amount": "المبلغ" } }, "UNAUTHORIZED_ERROR": "يجب تسجيل الدخول مره اخرى", diff --git a/src/i18n/en/general.json b/src/i18n/en/general.json index 87ebd1b..82fc26e 100644 --- a/src/i18n/en/general.json +++ b/src/i18n/en/general.json @@ -4,7 +4,103 @@ "paginationSize": "page size", "document": { "documentType": "Document type" - + }, + + "auth": { + "countryCode": "Country code", + "phoneNumber": "Phone number", + "deviceId": "Device ID", + "publicKey": "Public key", + "email": "Email", + "password": "Password", + "confirmPassword": "Confirm password", + "otp": "OTP", + "grantType": "Grant type", + "signature": "Signature", + "googleToken": "Google token", + "fcmToken": "FCM token", + "refreshToken": "Refresh token", + "qrToken": "QR token", + "passcode": "Passcode" + }, + + "customer": { + "firstName": "First name", + "lastName": "Last name", + "countryOfResidence": "Country of residence", + "dateOfBirth": "Date of birth", + "profilePictureId": "Profile picture ID", + "isEmailEnabled": "Is Email enabled", + "isSmsEnabled": "Is SMS enabled", + "isPushEnabled": "Is Push enabled" + }, + + "junior": { + "relationship": "Relationship", + "civilIdFrontId": "Civil ID front", + "civilIdBackId": "Civil ID back", + "color": "Color", + "avatarId": "Avatar ID" + }, + + "moneyRequest": { + "requestedAmount": "Requested amount", + "message": "Message", + "frequency": "Frequency", + "startDate": "Start date", + "endDate": "End date", + "status": "Status" + }, + + "goal": { + "category": { + "name": "Name" + }, + "name": "Name", + "description": "Description", + "dueDate": "Due date", + "targetAmount": "Target amount", + "categoryIds": "Category IDs", + "imageId": "Image ID", + "fundAmount": "Fund amount" + }, + + "task": { + "title": "Title", + "description": "Description", + "startDate": "Start date", + "dueDate": "Due date", + "rewardAmount": "Reward amount", + "frequency": "Frequency", + "isProofRequired": "Is proof required", + "imageId": "Image ID", + "juniorId": "Junior ID", + "status": "Status" + }, + + "gift": { + "name": "Name", + "description": "Description", + "color": "Color", + "amount": "Amount", + "imageId": "Image ID", + "recipientId": "Recipient ID", + "status": "Status" + }, + + "allowance": { + "name": "Name", + "amount": "Amount", + "type": "Type", + "startDate": "Start date", + "endDate": "End date", + "numberOfTransactions": "Number of transactions", + "juniorId": "Junior ID" + }, + "allowanceChangeRequest": { + "reason": "Reason", + "allowanceId": "Allowance ID", + "amount": "Amount" } }, "UNAUTHORIZED_ERROR": "You have to login again", diff --git a/src/i18n/en/validation.json b/src/i18n/en/validation.json index 5ce9fcd..22b9714 100644 --- a/src/i18n/en/validation.json +++ b/src/i18n/en/validation.json @@ -24,5 +24,6 @@ "IsValidExpiryDate": "$t({path}.PROPERTY_MAPPINGS.{property}) must be a valid expiry date", "IsEnglishOnly": "$t({path}.PROPERTY_MAPPINGS.{property}) must be in English", "IsAbove18": "$t({path}.PROPERTY_MAPPINGS.{property}) must be above 18 years", - "IsValidPhoneNumber": "$t({path}.PROPERTY_MAPPINGS.{property}) must be a valid phone number" + "IsValidPhoneNumber": "$t({path}.PROPERTY_MAPPINGS.{property}) must be a valid phone number", + "IsPositive": "$t({path}.PROPERTY_MAPPINGS.{property}) must be a positive number" } diff --git a/src/junior/controllers/junior.controller.ts b/src/junior/controllers/junior.controller.ts index c4004db..07fb95b 100644 --- a/src/junior/controllers/junior.controller.ts +++ b/src/junior/controllers/junior.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser, Public } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { PageOptionsRequestDto } from '~/core/dtos'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; @@ -15,6 +15,7 @@ import { JuniorService } from '../services'; @Controller('juniors') @ApiTags('Juniors') @ApiBearerAuth() +@ApiLangRequestHeader() export class JuniorController { constructor(private readonly juniorService: JuniorService) {} diff --git a/src/junior/dtos/request/create-junior-user.request.dto.ts b/src/junior/dtos/request/create-junior-user.request.dto.ts index b86abbf..307f37f 100644 --- a/src/junior/dtos/request/create-junior-user.request.dto.ts +++ b/src/junior/dtos/request/create-junior-user.request.dto.ts @@ -18,13 +18,13 @@ export class CreateJuniorUserRequestDto { phoneNumber!: string; @ApiProperty({ example: 'John' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.firstName' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.firstName' }) }) + @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'customer.firstName' }) }) + @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'customer.firstName' }) }) firstName!: string; @ApiProperty({ example: 'Doe' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.lastName' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.lastName' }) }) + @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'customer.lastName' }) }) + @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'customer.lastName' }) }) lastName!: string; @ApiProperty({ example: '2020-01-01' }) diff --git a/src/junior/dtos/request/set-theme.request.dto.ts b/src/junior/dtos/request/set-theme.request.dto.ts index 5aadb8c..643617f 100644 --- a/src/junior/dtos/request/set-theme.request.dto.ts +++ b/src/junior/dtos/request/set-theme.request.dto.ts @@ -1,13 +1,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEnum, IsUUID } from 'class-validator'; +import { i18nValidationMessage as i18n } from 'nestjs-i18n'; import { ThemeColor } from '~/junior/enums'; export class SetThemeRequestDto { @ApiProperty({ example: ThemeColor.VIOLET }) - @IsEnum(ThemeColor) + @IsEnum(ThemeColor, { message: i18n('validation.IsEnum', { path: 'general', property: 'junior.color' }) }) color!: ThemeColor; @ApiProperty({ example: 'fbfre-4f4f-4f4f-4f4f' }) - @IsUUID() + @IsUUID('4', { message: i18n('validation.IsUUID', { path: 'general', property: 'junior.avatarId' }) }) avatarId!: string; } diff --git a/src/money-request/controllers/money-requests.controller.ts b/src/money-request/controllers/money-requests.controller.ts index 3f45551..d7c8387 100644 --- a/src/money-request/controllers/money-requests.controller.ts +++ b/src/money-request/controllers/money-requests.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; import { CreateMoneyRequestRequestDto, MoneyRequestsFiltersRequestDto } from '../dtos/request'; @@ -14,6 +14,7 @@ import { MoneyRequestsService } from '../services'; @Controller('money-requests') @ApiTags('Money Requests') @ApiBearerAuth() +@ApiLangRequestHeader() export class MoneyRequestsController { constructor(private readonly moneyRequestsService: MoneyRequestsService) {} diff --git a/src/saving-goals/controllers/saving-goals.controller.ts b/src/saving-goals/controllers/saving-goals.controller.ts index 00c0992..22e65d6 100644 --- a/src/saving-goals/controllers/saving-goals.controller.ts +++ b/src/saving-goals/controllers/saving-goals.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse, ApiDataResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { PageOptionsRequestDto } from '~/core/dtos'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; @@ -23,6 +23,7 @@ import { CategoryService } from '../services/category.service'; @UseGuards(RolesGuard) @AllowedRoles(Roles.JUNIOR) @ApiBearerAuth() +@ApiLangRequestHeader() export class SavingGoalsController { constructor( private readonly savingGoalsService: SavingGoalsService, diff --git a/src/task/controllers/task.controller.ts b/src/task/controllers/task.controller.ts index 81265cb..773b868 100644 --- a/src/task/controllers/task.controller.ts +++ b/src/task/controllers/task.controller.ts @@ -4,7 +4,7 @@ import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser } from '~/common/decorators'; import { AccessTokenGuard, RolesGuard } from '~/common/guards'; -import { ApiDataPageResponse } from '~/core/decorators'; +import { ApiDataPageResponse, ApiLangRequestHeader } from '~/core/decorators'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; import { CreateTaskRequestDto, TaskSubmissionRequestDto } from '../dtos/request'; @@ -15,6 +15,7 @@ import { TaskService } from '../services'; @Controller('tasks') @ApiTags('Tasks') @ApiBearerAuth() +@ApiLangRequestHeader() export class TaskController { constructor(private readonly taskService: TaskService) {}