add dto validation and swagger schemas
This commit is contained in:
Generated
+30
@@ -557,6 +557,11 @@
|
|||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/validator": {
|
||||||
|
"version": "13.15.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
|
||||||
|
"integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA=="
|
||||||
|
},
|
||||||
"@webassemblyjs/ast": {
|
"@webassemblyjs/ast": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
|
||||||
@@ -1083,6 +1088,21 @@
|
|||||||
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
|
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"class-transformer": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
|
||||||
|
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw=="
|
||||||
|
},
|
||||||
|
"class-validator": {
|
||||||
|
"version": "0.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz",
|
||||||
|
"integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/validator": "^13.15.3",
|
||||||
|
"libphonenumber-js": "^1.11.1",
|
||||||
|
"validator": "^13.15.22"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cli-cursor": {
|
"cli-cursor": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||||
@@ -2247,6 +2267,11 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libphonenumber-js": {
|
||||||
|
"version": "1.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.13.1.tgz",
|
||||||
|
"integrity": "sha512-GEw0GLL7YUUA6nv21IsCvVjtI5Ejn84sjbdfQ9KxdbqEVOk1PZh7xejn01EEiniKw+dBeCfim+8MGeuvVuE2BA=="
|
||||||
|
},
|
||||||
"lines-and-columns": {
|
"lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
@@ -3476,6 +3501,11 @@
|
|||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"validator": {
|
||||||
|
"version": "13.15.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz",
|
||||||
|
"integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw=="
|
||||||
|
},
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"@nestjs/platform-express": "^10.4.8",
|
"@nestjs/platform-express": "^10.4.8",
|
||||||
"@nestjs/swagger": "^7.4.2",
|
"@nestjs/swagger": "^7.4.2",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
|
"class-transformer": "^0.5.1",
|
||||||
|
"class-validator": "^0.15.1",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"pg": "^8.13.1",
|
"pg": "^8.13.1",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
|
import { ValidationPipe } from '@nestjs/common';
|
||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
app.useGlobalPipes(
|
||||||
|
new ValidationPipe({
|
||||||
|
forbidNonWhitelisted: true,
|
||||||
|
transform: true,
|
||||||
|
whitelist: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const swaggerConfig = new DocumentBuilder()
|
const swaggerConfig = new DocumentBuilder()
|
||||||
.setTitle('Montime API')
|
.setTitle('Montime API')
|
||||||
.setDescription('Local services super app API')
|
.setDescription('Local services super app API')
|
||||||
|
|||||||
@@ -1,13 +1,53 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsArray,
|
||||||
|
IsBoolean,
|
||||||
|
IsEnum,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
MaxLength,
|
||||||
|
} from 'class-validator';
|
||||||
import { AttributeType } from '../../../entities/attribute-definition.entity';
|
import { AttributeType } from '../../../entities/attribute-definition.entity';
|
||||||
|
|
||||||
export class CreateAttributeDefinitionDto {
|
export class CreateAttributeDefinitionDto {
|
||||||
|
@ApiProperty({ example: 'Has Waiting Room' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
/** یکتا در محدوده همان دسته شغلی */
|
/** یکتا در محدوده همان دسته شغلی */
|
||||||
|
@ApiProperty({ example: 'has-waiting-room' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'key must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
key!: string;
|
key!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ enum: AttributeType, example: AttributeType.BOOLEAN })
|
||||||
|
@IsEnum(AttributeType)
|
||||||
type!: AttributeType;
|
type!: AttributeType;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
categoryId!: string;
|
categoryId!: string;
|
||||||
|
|
||||||
/** برای type=select آرایه گزینهها */
|
/** برای type=select آرایه گزینهها */
|
||||||
|
@ApiPropertyOptional({ type: [String], example: ['small', 'medium', 'large'] })
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
options?: string[];
|
options?: string[];
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: false })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isFilterable?: boolean;
|
isFilterable?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,59 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsArray,
|
||||||
|
IsBoolean,
|
||||||
|
IsEnum,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
MaxLength,
|
||||||
|
} from 'class-validator';
|
||||||
import { AttributeType } from '../../../entities/attribute-definition.entity';
|
import { AttributeType } from '../../../entities/attribute-definition.entity';
|
||||||
|
|
||||||
export class UpdateAttributeDefinitionDto {
|
export class UpdateAttributeDefinitionDto {
|
||||||
|
@ApiPropertyOptional({ example: 'Has Waiting Room' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'has-waiting-room' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'key must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
key?: string;
|
key?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ enum: AttributeType, example: AttributeType.BOOLEAN })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(AttributeType)
|
||||||
type?: AttributeType;
|
type?: AttributeType;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ format: 'uuid' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
categoryId?: string;
|
categoryId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
type: [String],
|
||||||
|
example: ['small', 'medium', 'large'],
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
options?: string[] | null;
|
options?: string[] | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: false })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isFilterable?: boolean;
|
isFilterable?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsString, Matches } from 'class-validator';
|
||||||
|
|
||||||
export class RequestOtpDto {
|
export class RequestOtpDto {
|
||||||
|
@ApiProperty({ example: '09122222222' })
|
||||||
|
@IsString()
|
||||||
|
@Matches(/^(\+?\d{10,15}|09\d{9})$/, {
|
||||||
|
message: 'mobile must be a valid mobile number',
|
||||||
|
})
|
||||||
mobile!: string;
|
mobile!: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,18 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsString, Matches } from 'class-validator';
|
||||||
|
|
||||||
export class VerifyOtpDto {
|
export class VerifyOtpDto {
|
||||||
|
@ApiProperty({ example: '09122222222' })
|
||||||
|
@IsString()
|
||||||
|
@Matches(/^(\+?\d{10,15}|09\d{9})$/, {
|
||||||
|
message: 'mobile must be a valid mobile number',
|
||||||
|
})
|
||||||
mobile!: string;
|
mobile!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: '123456' })
|
||||||
|
@IsString()
|
||||||
|
@Matches(/^\d{4,8}$/, {
|
||||||
|
message: 'code must be 4 to 8 digits',
|
||||||
|
})
|
||||||
code!: string;
|
code!: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsISO8601, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class CreateBookingDto {
|
export class CreateBookingDto {
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
customerId!: string;
|
customerId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
businessId!: string;
|
businessId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
businessServiceId!: string;
|
businessServiceId!: string;
|
||||||
|
|
||||||
/** ISO 8601 datetime string */
|
/** ISO 8601 datetime string */
|
||||||
|
@ApiProperty({ example: '2026-05-13T10:00:00.000Z' })
|
||||||
|
@IsISO8601()
|
||||||
scheduledAt!: string;
|
scheduledAt!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Test booking', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
note?: string | null;
|
note?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsEnum, IsISO8601, IsOptional, IsString, MaxLength } from 'class-validator';
|
||||||
import { BookingStatus } from '../../../entities/booking.entity';
|
import { BookingStatus } from '../../../entities/booking.entity';
|
||||||
|
|
||||||
export class UpdateBookingDto {
|
export class UpdateBookingDto {
|
||||||
|
@ApiPropertyOptional({ example: '2026-05-13T10:00:00.000Z' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsISO8601()
|
||||||
scheduledAt?: string;
|
scheduledAt?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ enum: BookingStatus, example: BookingStatus.CONFIRMED })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(BookingStatus)
|
||||||
status?: BookingStatus;
|
status?: BookingStatus;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Customer asked for morning slot', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
note?: string | null;
|
note?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class CreateBusinessAttributeValueDto {
|
export class CreateBusinessAttributeValueDto {
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
businessId!: string;
|
businessId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
attributeDefinitionId!: string;
|
attributeDefinitionId!: string;
|
||||||
|
|
||||||
/** مقدار به صورت رشته ذخیره میشود؛ برای boolean مثلا true/false */
|
/** مقدار به صورت رشته ذخیره میشود؛ برای boolean مثلا true/false */
|
||||||
|
@ApiPropertyOptional({ example: 'true', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
value?: string | null;
|
value?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsOptional, IsString, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateBusinessAttributeValueDto {
|
export class UpdateBusinessAttributeValueDto {
|
||||||
|
@ApiPropertyOptional({ example: 'true', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
value?: string | null;
|
value?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsOptional, IsString, Matches, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class CreateBusinessCategoryDto {
|
export class CreateBusinessCategoryDto {
|
||||||
|
@ApiProperty({ example: 'Car Wash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 'car-wash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug!: string;
|
slug!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,24 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsOptional, IsString, Matches, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateBusinessCategoryDto {
|
export class UpdateBusinessCategoryDto {
|
||||||
|
@ApiPropertyOptional({ example: 'Car Wash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'car-wash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug?: string;
|
slug?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,31 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsInt, IsNumber, IsOptional, IsUUID, Max, Min } from 'class-validator';
|
||||||
|
|
||||||
export class CreateBusinessServiceDto {
|
export class CreateBusinessServiceDto {
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
businessId!: string;
|
businessId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
serviceTemplateId!: string;
|
serviceTemplateId!: string;
|
||||||
|
|
||||||
/** قیمت به واحد پول (عدد اعشاری مجاز است) */
|
/** قیمت به واحد پول (عدد اعشاری مجاز است) */
|
||||||
|
@ApiProperty({ example: 100000 })
|
||||||
|
@IsNumber({ maxDecimalPlaces: 2 })
|
||||||
|
@Min(0)
|
||||||
price!: number;
|
price!: number;
|
||||||
|
|
||||||
/** اگر خالی باشد از template.defaultDurationMinutes استفاده میشود */
|
/** اگر خالی باشد از template.defaultDurationMinutes استفاده میشود */
|
||||||
|
@ApiPropertyOptional({ example: 30, nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Min(1)
|
||||||
|
@Max(1440)
|
||||||
durationMinutes?: number | null;
|
durationMinutes?: number | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsInt, IsNumber, IsOptional, IsUUID, Max, Min } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateBusinessServiceDto {
|
export class UpdateBusinessServiceDto {
|
||||||
|
@ApiPropertyOptional({ format: 'uuid' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
serviceTemplateId?: string;
|
serviceTemplateId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 100000 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber({ maxDecimalPlaces: 2 })
|
||||||
|
@Min(0)
|
||||||
price?: number;
|
price?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 30, nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Min(1)
|
||||||
|
@Max(1440)
|
||||||
durationMinutes?: number | null;
|
durationMinutes?: number | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsOptional, IsString, Matches, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
export class AssignBusinessOwnerDto {
|
export class AssignBusinessOwnerDto {
|
||||||
|
@ApiProperty({ example: '09111111111' })
|
||||||
|
@IsString()
|
||||||
|
@Matches(/^(\+?\d{10,15}|09\d{9})$/, {
|
||||||
|
message: 'mobile must be a valid mobile number',
|
||||||
|
})
|
||||||
mobile!: string;
|
mobile!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Business Admin', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
fullName?: string | null;
|
fullName?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,68 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsLatitude,
|
||||||
|
IsLongitude,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
MaxLength,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateBusinessDto {
|
export class CreateBusinessDto {
|
||||||
|
@ApiProperty({ example: 'Shine Carwash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 'shine-carwash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug!: string;
|
slug!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
categoryId!: string;
|
categoryId!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Premium carwash service' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: '09123456789' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(20)
|
||||||
contactPhone?: string;
|
contactPhone?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Main street' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
address?: string;
|
address?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 35.6892 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsLatitude()
|
||||||
latitude?: number;
|
latitude?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 51.389 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsLongitude()
|
||||||
longitude?: number;
|
longitude?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ format: 'uuid' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
ownerId?: string;
|
ownerId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,71 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsLatitude,
|
||||||
|
IsLongitude,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
MaxLength,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class UpdateBusinessDto {
|
export class UpdateBusinessDto {
|
||||||
|
@ApiPropertyOptional({ example: 'Shine Carwash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'shine-carwash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug?: string;
|
slug?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ format: 'uuid' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
categoryId?: string;
|
categoryId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Premium carwash service', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: '09123456789', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(20)
|
||||||
contactPhone?: string | null;
|
contactPhone?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Main street', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
address?: string | null;
|
address?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 35.6892, nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsLatitude()
|
||||||
latitude?: number | null;
|
latitude?: number | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 51.389, nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsLongitude()
|
||||||
longitude?: number | null;
|
longitude?: number | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ format: 'uuid', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
ownerId?: string | null;
|
ownerId?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,49 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsInt,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
Max,
|
||||||
|
MaxLength,
|
||||||
|
Min,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateServiceTemplateDto {
|
export class CreateServiceTemplateDto {
|
||||||
|
@ApiProperty({ example: 'Basic Wash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 'basic-wash' })
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug!: string;
|
slug!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ format: 'uuid' })
|
||||||
|
@IsUUID()
|
||||||
categoryId!: string;
|
categoryId!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Exterior wash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 30 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Min(1)
|
||||||
|
@Max(1440)
|
||||||
defaultDurationMinutes?: number;
|
defaultDurationMinutes?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,52 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsInt,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
Matches,
|
||||||
|
Max,
|
||||||
|
MaxLength,
|
||||||
|
Min,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class UpdateServiceTemplateDto {
|
export class UpdateServiceTemplateDto {
|
||||||
|
@ApiPropertyOptional({ example: 'Basic Wash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'basic-wash' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(120)
|
||||||
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
||||||
|
message: 'slug must be lowercase words separated by hyphens',
|
||||||
|
})
|
||||||
slug?: string;
|
slug?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ format: 'uuid' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
categoryId?: string;
|
categoryId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'Exterior wash', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 30 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Min(1)
|
||||||
|
@Max(1440)
|
||||||
defaultDurationMinutes?: number;
|
defaultDurationMinutes?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
|
||||||
import { UserRole } from '../../../entities/user.entity';
|
import { UserRole } from '../../../entities/user.entity';
|
||||||
|
|
||||||
export class UpdateUserDto {
|
export class UpdateUserDto {
|
||||||
|
@ApiPropertyOptional({ example: 'Mahdi', nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(150)
|
||||||
fullName?: string | null;
|
fullName?: string | null;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ enum: UserRole, example: UserRole.BUSINESS_OWNER })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(UserRole)
|
||||||
role?: UserRole;
|
role?: UserRole;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user