Initial commit: Meshkee CMS API

NestJS backend with Prisma, Docker Compose for Postgres/Redis, and deploy docs for the production VM.
This commit is contained in:
Ali Reza
2026-07-21 17:52:36 +03:30
commit bb59d5e9ba
254 changed files with 37031 additions and 0 deletions
+223
View File
@@ -0,0 +1,223 @@
import { Transform, Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsInt,
IsNumber,
IsOptional,
IsString,
Min,
MinLength,
ValidateNested,
} from 'class-validator';
export class StoreItemVariantSelectionDto {
@IsString()
@MinLength(1)
variationId!: string;
@IsString()
@MinLength(1)
optionId!: string;
}
export class CreateStoreItemVariantDto {
@IsArray()
@ValidateNested({ each: true })
@Type(() => StoreItemVariantSelectionDto)
selections!: StoreItemVariantSelectionDto[];
@IsOptional()
@IsNumber()
@Min(0)
price?: number;
@IsOptional()
@IsInt()
@Min(0)
stockQuantity?: number;
}
export class BatchCreateStoreItemsDto {
@IsString()
@MinLength(1)
productId!: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateStoreItemVariantDto)
items!: CreateStoreItemVariantDto[];
}
export class ListStoreItemsDto {
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number;
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
pageSize?: number;
}
export class ListPublicStoreItemsDto {
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number;
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
pageSize?: number;
@IsOptional()
@IsString()
categoryId?: string;
@IsOptional()
@IsString()
brandId?: string;
@IsOptional()
@IsString()
productId?: string;
@IsOptional()
@IsString()
name?: string;
@IsOptional()
@Transform(({ value }) => value === 'true' || value === true)
@IsBoolean()
inStock?: boolean;
@IsOptional()
@Transform(({ value }) => value === 'true' || value === true)
@IsBoolean()
isFestival?: boolean;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
minPrice?: number;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
maxPrice?: number;
}
export class UpdateStoreItemVariantDto {
@IsOptional()
@IsNumber()
@Min(0)
price?: number;
@IsOptional()
@IsInt()
@Min(0)
stockQuantity?: number;
@IsOptional()
@IsNumber()
@Min(0)
discountedPrice?: number | null;
@IsOptional()
isFestival?: boolean;
}
export class BatchUpdateStoreItemDiscountDto {
@IsString()
@MinLength(1)
id!: string;
@IsOptional()
@IsNumber()
@Min(0)
discountedPrice?: number | null;
}
export class BatchUpdateStoreItemDiscountsDto {
@IsString()
@MinLength(1)
productId!: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => BatchUpdateStoreItemDiscountDto)
items!: BatchUpdateStoreItemDiscountDto[];
}
export class SyncStoreItemVariantRowDto {
@IsOptional()
@IsString()
id?: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => StoreItemVariantSelectionDto)
selections!: StoreItemVariantSelectionDto[];
@IsNumber()
@Min(0)
price!: number;
@IsInt()
@Min(0)
stockQuantity!: number;
}
export class SyncProductStoreItemVariantsDto {
@IsString()
@MinLength(1)
productId!: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => SyncStoreItemVariantRowDto)
items!: SyncStoreItemVariantRowDto[];
@IsArray()
@IsString({ each: true })
removedIds!: string[];
}
export class BatchUpdateFestivalRewardDto {
@IsString()
@MinLength(1)
id!: string;
@IsOptional()
@IsInt()
@Min(0)
rewardPoints?: number | null;
}
export class BatchUpdateFestivalRewardsDto {
@IsString()
@MinLength(1)
productId!: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => BatchUpdateFestivalRewardDto)
items!: BatchUpdateFestivalRewardDto[];
}
// Backward-compatible aliases for existing imports
export {
StoreItemVariantSelectionDto as StoreItemSelectionDto,
CreateStoreItemVariantDto as CreateStoreItemDto,
UpdateStoreItemVariantDto as UpdateStoreItemDto,
SyncStoreItemVariantRowDto as SyncStoreItemRowDto,
SyncProductStoreItemVariantsDto as SyncProductStoreItemsDto,
};