This commit is contained in:
mahyargdz
2025-09-14 15:15:03 +03:30
commit be82059172
534 changed files with 51310 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
import mongoose from "mongoose";
import { Logger } from "../core/logging/logger";
export const clearDatabase = async (logger: Logger) => {
try {
const db = mongoose.connection.db;
if (db) {
// Get all collections
const collections = await db.listCollections().toArray();
collections
.map((collection) => collection.name)
.forEach(async (collectionName) => {
logger.debug(`Dropped collection: ${collectionName}`, "Database");
await db.dropCollection(collectionName);
});
}
} catch (error) {
logger.error(`error happened in drop collections`, error);
}
const collections = mongoose.connection.collections;
for (const key in collections) {
const collection = collections[key];
try {
await collection.drop();
logger.debug(`Dropped collection: ${key}`, "Database");
} catch (error: unknown) {
if (error instanceof Error) {
if (error.message === "ns not found") {
logger.warn(`Collection not found: ${key}`, "Database");
continue;
} else if (error.message.includes("a background operation is currently running")) {
logger.warn(`Skipping collection due to background operation: ${key}`, "Database");
continue;
} else {
throw error;
}
}
}
}
};
+18
View File
@@ -0,0 +1,18 @@
import Redis from "ioredis";
import mongoose from "mongoose";
const MONGO_URI = process.env.MONGO_URI as string;
export const connectMongo = async () => {
await mongoose.connect(MONGO_URI, { serverSelectionTimeoutMS: 2000 });
};
export const connectRedis = () => {
// return new Redis({
// host: process.env.REDIS_HOST,
// port: process.env.REDIS_PORT ? parseInt(process.env.REDIS_PORT) : 6379,
// password: process.env.REDIS_PASSWORD,
// maxRetriesPerRequest: null,
// });
return new Redis(process.env.REDIS_URI, { maxRetriesPerRequest: null });
};
+33
View File
@@ -0,0 +1,33 @@
[
{ "id": 1, "name": "آذربایجان شرقی" },
{ "id": 2, "name": "آذربایجان غربی" },
{ "id": 3, "name": "اردبیل" },
{ "id": 4, "name": "اصفهان" },
{ "id": 5, "name": "البرز" },
{ "id": 6, "name": "ایلام" },
{ "id": 7, "name": "بوشهر" },
{ "id": 8, "name": "تهران" },
{ "id": 9, "name": "چهارمحال وبختیاری" },
{ "id": 10, "name": "خراسان جنوبی" },
{ "id": 11, "name": "خراسان رضوی" },
{ "id": 12, "name": "خراسان شمالی" },
{ "id": 13, "name": "خوزستان" },
{ "id": 14, "name": "زنجان" },
{ "id": 15, "name": "سمنان" },
{ "id": 16, "name": "سیستان وبلوچستان" },
{ "id": 17, "name": "فارس" },
{ "id": 18, "name": "قزوین" },
{ "id": 19, "name": "قم" },
{ "id": 20, "name": "کردستان" },
{ "id": 21, "name": "کرمان" },
{ "id": 22, "name": "کرمانشاه" },
{ "id": 23, "name": "کهگیلویه وبویراحمد" },
{ "id": 24, "name": "گلستان" },
{ "id": 25, "name": "گیلان" },
{ "id": 26, "name": "لرستان" },
{ "id": 27, "name": "مازندران" },
{ "id": 28, "name": "مرکزی" },
{ "id": 29, "name": "هرمزگان" },
{ "id": 30, "name": "همدان" },
{ "id": 31, "name": "یزد" }
]
File diff suppressed because it is too large Load Diff
+671
View File
@@ -0,0 +1,671 @@
import { faker } from "@faker-js/faker";
import { CreateProductStep, ProductSource, ProductStatus } from "../../common/enums/product.enum";
import { SellerType } from "../../common/enums/seller.enum";
import { OwnerRef } from "../../modules/shop/models/Abstraction/IShop";
faker.locale = "fa";
export const fakeImageGenerator = () => faker.image.imageUrl();
export const CreateFakeSellerData = () => ({
fullName: faker.name.fullName(),
shebaNumber: faker.finance.iban(),
dateOfBirth: "1360/08/25",
phoneNumber: faker.phone.number("0912#######"),
telephoneNumber: faker.phone.number("0863#######"),
nationalCode: faker.random.numeric(10),
email: faker.internet.email(crypto.randomUUID().slice(0, 5)),
profilePhoto: faker.image.abstract(),
type: faker.helpers.arrayElement([SellerType.RETAILER, SellerType.WHOLESALER]),
});
export const createFakeShopData = (shipmentMethod: number[], owner: string) => ({
shopName: `فروشگاه ${faker.commerce.department()}`,
shopDescription: "تست",
telephoneNumber: faker.phone.number("0863#######"),
shopNationalId: faker.random.numeric(10),
shopPostalCode: faker.random.numeric(10),
logo: faker.image.imageUrl(),
rate: {
totalRate: faker.datatype.number({ min: 1, max: 5 }),
totalCount: faker.datatype.number({ min: 1, max: 1000 }),
onTimeShip: faker.datatype.number({ min: 1, max: 5 }),
returns: faker.datatype.number({ min: 1, max: 5 }),
cancel: faker.datatype.number({ min: 1, max: 5 }),
},
shipmentMethod,
owner,
ownerRef: OwnerRef.SELLER,
});
export const fakeProductsData = [
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "تلویزیون ال ای دی سامسونگ",
// title_en: "Samsung LED TV",
// model: "SAMSUNG123",
// source: ProductSource.LOCAL,
// description: "تلویزیون ال ای دی 55 اینچ سامسونگ با کیفیت تصویر 4K",
// metaDescription: "تلویزیون ال ای دی سامسونگ 4K",
// tags: ["ال ای دی", "سامسونگ", "4K"],
// advantages: ["کیفیت تصویر عالی", "قاب باریک"],
// disAdvantages: ["قیمت بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "ماشین لباسشویی ال جی",
// title_en: "LG Washing Machine",
// model: "LGWASH456",
// source: ProductSource.IMPORT,
// description: "ماشین لباسشویی 8 کیلوگرمی ال جی با تکنولوژی بخار شوی",
// metaDescription: "ماشین لباسشویی ال جی با ظرفیت 8 کیلوگرم",
// tags: ["لباسشویی", "ال جی", "بخار شوی"],
// advantages: ["مصرف انرژی کم", "سرعت چرخش بالا"],
// disAdvantages: ["صدا در حالت خشک کن"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "یخچال ساید بای ساید بوش",
// title_en: "Bosch Side by Side Refrigerator",
// model: "BOSCHFRIDGE789",
// source: ProductSource.LOCAL,
// description: "یخچال فریزر ساید بای ساید بوش با ظرفیت 30 فوت",
// metaDescription: "یخچال فریزر ساید بای ساید بوش",
// tags: ["یخچال", "بوش", "ساید بای ساید"],
// advantages: ["ظرفیت بالا", "طراحی مدرن"],
// disAdvantages: ["قیمت بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
{
color: true,
size: false,
meterage: false,
title_fa: "موبایل آیفون 13",
title_en: "iPhone 13",
model: "IPHONE13PRO",
source: ProductSource.IMPORT,
description: "گوشی آیفون 13 پرو با حافظه 256 گیگابایت و دوربین سه‌گانه",
metaDescription: "آیفون 13 پرو با حافظه 256 گیگ",
tags: ["آیفون", "اپل", "موبایل"],
advantages: ["دوربین عالی", "عملکرد سریع"],
disAdvantages: ["قیمت بسیار بالا"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: true,
size: false,
meterage: false,
title_fa: "لپ‌تاپ ایسوس",
title_en: "Asus Laptop",
model: "ASUSLAP234",
source: ProductSource.LOCAL,
description: "لپ‌تاپ ایسوس با پردازنده Core i7 و حافظه 16 گیگابایت",
metaDescription: "لپ‌تاپ ایسوس با حافظه 16 گیگ",
tags: ["لپ‌تاپ", "ایسوس", "Core i7"],
advantages: ["عملکرد قوی", "صفحه‌نمایش با کیفیت"],
disAdvantages: ["عمر باتری پایین"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: true,
size: false,
meterage: false,
title_fa: "ساعت هوشمند اپل واچ",
title_en: "Apple Watch",
model: "APPLEWATCH123",
source: ProductSource.IMPORT,
description: "ساعت هوشمند اپل با قابلیت اندازه‌گیری ضربان قلب",
metaDescription: "اپل واچ سری 6",
tags: ["ساعت هوشمند", "اپل", "واچ"],
advantages: ["اندازه‌گیری سلامت", "طراحی زیبا"],
disAdvantages: ["عمر باتری محدود"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "تبلت سامسونگ گلکسی تب",
// title_en: "Samsung Galaxy Tab",
// model: "SAMGALTAB567",
// source: ProductSource.LOCAL,
// description: "تبلت سامسونگ گلکسی تب با صفحه نمایش 10.5 اینچ",
// metaDescription: "تبلت سامسونگ گلکسی",
// tags: ["تبلت", "سامسونگ", "گلکسی"],
// advantages: ["صفحه نمایش بزرگ", "قابلیت چند وظیفگی"],
// disAdvantages: ["عمر باتری متوسط"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "دوربین عکاسی نیکون",
// title_en: "Nikon Camera",
// model: "NIKONCAM123",
// source: ProductSource.IMPORT,
// description: "دوربین دیجیتال نیکون با سنسور 24 مگاپیکسل",
// metaDescription: "دوربین نیکون دیجیتال",
// tags: ["دوربین", "نیکون", "دیجیتال"],
// advantages: ["کیفیت تصویر بالا", "سنسور قوی"],
// disAdvantages: ["بدنه سنگین"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "اسپیکر بلوتوثی جی بی ال",
// title_en: "JBL Bluetooth Speaker",
// model: "JBLSPK789",
// source: ProductSource.LOCAL,
// description: "اسپیکر بلوتوثی جی بی ال با کیفیت صدای عالی",
// metaDescription: "اسپیکر جی بی ال بلوتوث",
// tags: ["اسپیکر", "بلوتوث", "جی بی ال"],
// advantages: ["کیفیت صدای عالی", "قابلیت حمل آسان"],
// disAdvantages: ["قیمت نسبتاً بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "هدفون بی سیم سونی",
// title_en: "Sony Wireless Headphones",
// model: "SONYWH123",
// source: ProductSource.IMPORT,
// description: "هدفون بی سیم سونی با قابلیت حذف نویز",
// metaDescription: "هدفون بی سیم سونی",
// tags: ["هدفون", "بی سیم", "سونی"],
// advantages: ["حذف نویز عالی", "طراحی ارگونومیک"],
// disAdvantages: ["قیمت بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "دوربین فیلمبرداری سونی",
// title_en: "Sony Camcorder",
// model: "SONYCAM456",
// source: ProductSource.LOCAL,
// description: "دوربین فیلمبرداری سونی با قابلیت فیلم‌برداری 4K",
// metaDescription: "دوربین فیلمبرداری 4K سونی",
// tags: ["دوربین", "فیلمبرداری", "سونی"],
// advantages: ["فیلم‌برداری 4K", "باتری با عمر طولانی"],
// disAdvantages: ["وزن سنگین"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "گوشی شیائومی می 11",
// title_en: "Xiaomi Mi 11",
// model: "MI11PRO",
// source: ProductSource.IMPORT,
// description: "گوشی موبایل شیائومی می 11 پرو با حافظه 256 گیگابایت",
// metaDescription: "گوشی شیائومی می 11 پرو",
// tags: ["شیائومی", "موبایل", "می 11"],
// advantages: ["دوربین قوی", "پردازنده سریع"],
// disAdvantages: ["شارژر جداگانه فروخته می‌شود"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "تلویزیون ال جی OLED",
// title_en: "LG OLED TV",
// model: "LGOLED789",
// source: ProductSource.LOCAL,
// description: "تلویزیون 65 اینچ ال جی با کیفیت تصویر OLED",
// metaDescription: "تلویزیون OLED ال جی",
// tags: ["تلویزیون", "ال جی", "OLED"],
// advantages: ["کیفیت تصویر عالی", "طراحی باریک"],
// disAdvantages: ["قیمت بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "پاوربانک انکر",
// title_en: "Anker Power Bank",
// model: "ANKERPB100",
// source: ProductSource.IMPORT,
// description: "پاوربانک انکر با ظرفیت 20000 میلی‌آمپر ساعت",
// metaDescription: "پاوربانک انکر با ظرفیت بالا",
// tags: ["پاوربانک", "انکر", "ظرفیت بالا"],
// advantages: ["ظرفیت بزرگ", "شارژ سریع"],
// disAdvantages: ["وزن بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: false,
// size: false,
// meterage: false,
// title_fa: "کنسول بازی پلی استیشن 5",
// title_en: "PlayStation 5",
// model: "PS5DISC",
// source: ProductSource.IMPORT,
// description: "کنسول بازی پلی استیشن 5 با دیسک درایو",
// metaDescription: "کنسول بازی پلی استیشن 5",
// tags: ["کنسول", "پلی استیشن", "بازی"],
// advantages: ["بازی‌های انحصاری", "گرافیک فوق‌العاده"],
// disAdvantages: ["موجودی کم"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "هدفون بی سیم بوز",
// title_en: "Bose Wireless Headphones",
// model: "BOSEWH789",
// source: ProductSource.IMPORT,
// description: "هدفون بی سیم بوز با قابلیت حذف نویز فعال",
// metaDescription: "هدفون بی سیم بوز",
// tags: ["هدفون", "بی سیم", "بوز"],
// advantages: ["کیفیت صدای بالا", "حذف نویز"],
// disAdvantages: ["قیمت بالا"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "تبلت هواوی مدیاپد",
// title_en: "Huawei MediaPad",
// model: "HUAWEITAB1",
// source: ProductSource.LOCAL,
// description: "تبلت هواوی مدیاپد با صفحه نمایش 10.8 اینچی",
// metaDescription: "تبلت هواوی مدیاپد",
// tags: ["تبلت", "هواوی", "مدیاپد"],
// advantages: ["صفحه نمایش بزرگ", "طراحی سبک"],
// disAdvantages: ["عملکرد متوسط در بازی"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "اسپیکر بلوتوثی سونی",
// title_en: "Sony Bluetooth Speaker",
// model: "SONYSPK234",
// source: ProductSource.IMPORT,
// description: "اسپیکر بلوتوثی سونی با کیفیت صدای عالی",
// metaDescription: "اسپیکر بلوتوثی سونی",
// tags: ["اسپیکر", "بلوتوث", "سونی"],
// advantages: ["صدای شفاف", "طراحی مقاوم در برابر آب"],
// disAdvantages: ["عمر باتری محدود"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "موبایل نوکیا G20",
// title_en: "Nokia G20",
// model: "NOKIAG20",
// source: ProductSource.LOCAL,
// description: "گوشی موبایل نوکیا G20 با حافظه 128 گیگابایت",
// metaDescription: "گوشی نوکیا G20",
// tags: ["نوکیا", "موبایل", "G20"],
// advantages: ["باتری بادوام", "طراحی مقاوم"],
// disAdvantages: ["دوربین متوسط"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: true,
// size: false,
// meterage: false,
// title_fa: "مایکروویو پاناسونیک",
// title_en: "Panasonic Microwave",
// model: "PANAMW234",
// source: ProductSource.IMPORT,
// description: "مایکروویو پاناسونیک با قدرت 1200 وات",
// metaDescription: "مایکروویو پاناسونیک",
// tags: ["مایکروویو", "پاناسونیک", "پخت سریع"],
// advantages: ["پخت سریع", "قابلیت گریل"],
// disAdvantages: ["فضای داخلی کوچک"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
{
color: false,
size: true,
meterage: false,
title_fa: "تی شرت مردانه",
title_en: "mardane t-shirt",
model: "Nike",
source: ProductSource.IMPORT,
description: "تی شرت سبک و راحت مردانه نایک",
metaDescription: "تی شرت مردانه نایک برای ورزش و استفاده روزمره",
tags: ["تی شرت", "نایک", "لباس مردانه"],
advantages: ["پارچه سبک", "مناسب برای تابستان"],
disAdvantages: ["محدودیت رنگ"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: false,
size: false,
meterage: true,
title_fa: "فرش ماشینی",
title_en: "farsh mashini",
model: "Iranian Classic",
source: ProductSource.LOCAL,
description: "فرش ماشینی با طرح کلاسیک ایرانی",
metaDescription: "فرش ماشینی با کیفیت بالا و طرح سنتی ایرانی",
tags: ["فرش", "ماشینی", "کلاسیک"],
advantages: ["طرح زیبا", "قابلیت شستشو"],
disAdvantages: ["سنگین بودن"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: false,
size: true,
meterage: false,
title_fa: "شلوار جین زنانه",
title_en: "zanane jean pants",
model: "Levi's",
source: ProductSource.IMPORT,
description: "شلوار جین زنانه با استایل اسپرت",
metaDescription: "شلوار جین زنانه مناسب برای استفاده روزمره",
tags: ["شلوار جین", "زنانه", "لباس"],
advantages: ["کیفیت بالا", "راحتی"],
disAdvantages: ["قیمت بالا"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: false,
size: true,
meterage: false,
title_fa: "پیراهن مجلسی زنانه",
title_en: "zanane dress",
model: "Zara",
source: ProductSource.IMPORT,
description: "پیراهن مجلسی شیک زنانه برند زارا",
metaDescription: "پیراهن زنانه شیک برای مجالس و مهمانی‌ها",
tags: ["پیراهن", "مجلسی", "زنانه", "زارا"],
advantages: ["مدل زیبا", "جنس با کیفیت"],
disAdvantages: ["حساس به شستشو"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: false,
size: false,
meterage: true,
title_fa: "پرده اتاق خواب",
title_en: "bedroom curtain",
model: "LuxDecor",
source: ProductSource.LOCAL,
description: "پرده اتاق خواب با طرح مدرن و زیبا",
metaDescription: "پرده اتاق خواب شیک و جذاب با جنس مقاوم",
tags: ["پرده", "اتاق خواب", "دکوراسیون"],
advantages: ["نورگیر خوب", "نصب آسان"],
disAdvantages: ["قابلیت چین‌خوردگی"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
// {
// color: false,
// size: true,
// meterage: false,
// title_fa: "کفش ورزشی مردانه",
// title_en: "sport shoes",
// model: "Adidas",
// source: ProductSource.IMPORT,
// description: "کفش ورزشی مردانه مناسب دویدن",
// metaDescription: "کفش ورزشی سبک و راحت برای فعالیت‌های ورزشی",
// tags: ["کفش", "ورزشی", "مردانه", "آدیداس"],
// advantages: ["کفی نرم", "سبک"],
// disAdvantages: ["عدم مقاومت در برابر آب"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
{
color: false,
size: false,
meterage: true,
title_fa: "کفپوش چوبی",
title_en: "wooden flooring",
model: "WoodMaster",
source: ProductSource.LOCAL,
description: "کفپوش چوبی با کیفیت برای اتاق‌ها و سالن",
metaDescription: "کفپوش چوبی مقاوم با ظاهر زیبا",
tags: ["کفپوش", "چوبی", "دکوراسیون"],
advantages: ["زیبایی طبیعی", "مقاومت بالا"],
disAdvantages: ["نیاز به مراقبت ویژه"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
{
color: false,
size: true,
meterage: false,
title_fa: "کت چرمی مردانه",
title_en: "leather jacket",
model: "Tommy Hilfiger",
source: ProductSource.IMPORT,
description: "کت چرمی شیک مردانه برند تامی هیلفیگر",
metaDescription: "کت چرمی مردانه با کیفیت و استایل خاص",
tags: ["کت", "چرمی", "مردانه", "تامی"],
advantages: ["گرم و بادوام", "استایل خاص"],
disAdvantages: ["نیاز به مراقبت از چرم"],
isFake: false,
imagesUrl: {
cover: faker.image.imageUrl(),
list: [faker.image.imageUrl(), faker.image.imageUrl()],
},
step: CreateProductStep.Image,
status: ProductStatus.Approved,
},
// {
// color: false,
// size: true,
// meterage: false,
// title_fa: "هودی دخترانه",
// title_en: "hoodie",
// model: "Puma",
// source: ProductSource.IMPORT,
// description: "هودی گرم و راحت دخترانه برند پوما",
// metaDescription: "هودی دخترانه مناسب فصل پاییز و زمستان",
// tags: ["هودی", "دخترانه", "پوشاک", "پوما"],
// advantages: ["گرم و نرم", "کلاه قابل تنظیم"],
// disAdvantages: ["محدودیت رنگ"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
// {
// color: false,
// size: false,
// meterage: true,
// title_fa: "کاغذ دیواری مدرن",
// title_en: "modern wallpaper",
// model: "ArtWall",
// source: ProductSource.IMPORT,
// description: "کاغذ دیواری مدرن با طرح‌های جدید و زیبا",
// metaDescription: "کاغذ دیواری با طرح‌های مدرن برای دکوراسیون داخلی",
// tags: ["کاغذ دیواری", "دکوراسیون", "مدرن"],
// advantages: ["نصب آسان", "قابلیت شستشو"],
// disAdvantages: ["نیاز به دیوار صاف"],
// isFake: false,
// imagesUrl: {
// cover: faker.image.imageUrl(),
// list: [faker.image.imageUrl(), faker.image.imageUrl()],
// },
// step: CreateProductStep.Image,
// status: ProductStatus.Approved,
// },
];
+45
View File
@@ -0,0 +1,45 @@
import mongoose from "mongoose";
import { CategoryModel } from "../../modules/category/models/category.model";
// Create the Category model
export async function backfillHierarchy() {
try {
console.log("Starting hierarchy backfill...");
// Fetch all categories
const categories = await CategoryModel.find();
// Helper function to recursively update hierarchy
const updateHierarchy = async (categoryId: mongoose.Types.ObjectId, parentHierarchy: mongoose.Types.ObjectId[] = []) => {
const category = await CategoryModel.findById(categoryId);
if (!category) return;
const currentHierarchy = [...parentHierarchy, category._id];
// Update the category's hierarchy
category.hierarchy = currentHierarchy;
await category.save();
// Find child categories and update their hierarchy
const childCategories = await CategoryModel.find({ parent: category._id });
for (const child of childCategories) {
await updateHierarchy(child._id, currentHierarchy);
}
};
// Find all top-level categories (categories with no parent)
const topLevelCategories = categories.filter((category) => !category.parent);
// Update hierarchy for all top-level categories and their descendants
for (const topCategory of topLevelCategories) {
await updateHierarchy(topCategory._id);
}
console.log("Hierarchy backfill completed successfully!");
} catch (err) {
console.error("Error during hierarchy backfill:", err);
}
}
+41
View File
@@ -0,0 +1,41 @@
import { Logger } from "../../core/logging/logger";
import { BlogCategoryModel } from "../../modules/blog/models/blogCategory.model";
export const blogCategorySeeder = async (logger: Logger) => {
try {
const categories = [
{
title_fa: "الکترونیک",
slug: "electronics",
description: "آخرین اخبار و مقالات مربوط به محصولات الکترونیکی",
},
{
title_fa: "مد و پوشاک",
slug: "fashion",
description: "مقالات درباره مد، پوشاک و جدیدترین ترندهای فشن",
},
{
title_fa: "خانه و آشپزخانه",
slug: "home-kitchen",
description: "راهنمایی‌ها و مقالات مرتبط با محصولات خانه و آشپزخانه",
},
{
title_fa: "زیبایی و سلامت",
slug: "beauty-health",
description: "مقالات درباره زیبایی، مراقبت از پوست و سلامت",
},
{
title_fa: "بازی و سرگرمی",
slug: "gaming-entertainment",
description: "آخرین اخبار و مقالات مربوط به بازی‌ها و سرگرمی‌ها",
},
];
logger.info("start seeding Blog categories.");
await BlogCategoryModel.insertMany(categories);
logger.info("Blog categories seeded successfully");
} catch (error) {
logger.error("Error seeding blog categories:", error);
}
};
+239
View File
@@ -0,0 +1,239 @@
import { Logger } from "../../core/logging/logger";
import { AdminModel } from "../../modules/admin/models/admin.model";
import { IBlog } from "../../modules/blog/models/Abstraction/IBlog";
import { BlogModel } from "../../modules/blog/models/blog.model";
import { BlogCategoryModel } from "../../modules/blog/models/blogCategory.model";
import { fakeImageGenerator } from "../data/product";
export const blogSeeder = async (logger: Logger) => {
try {
const admin = await AdminModel.findOne({ userName: "defaultAdmin" });
const categories = await BlogCategoryModel.find();
if (categories.length === 0) {
logger.error("No blog categories found. Please run the blogCategorySeeder first.");
throw new Error("No blog categories found. Please run the blogCategorySeeder first.");
}
const blogs: IBlog[] = [];
categories.forEach((category) => {
switch (category.slug) {
case "electronics":
blogs.push(
{
title_fa: "برترین گوشی‌های هوشمند سال ۲۰۲۴",
slug: "top-smartphones-2024",
category: category._id,
description: "مروری بر بهترین گوشی‌های هوشمند عرضه شده در سال ۲۰۲۴.",
content:
"در سال ۲۰۲۴، شرکت‌های بزرگ تکنولوژی گوشی‌های هوشمند جدیدی معرفی کردند که شامل ویژگی‌ها و قابلیت‌های پیشرفته‌ای هستند...",
author: admin!._id,
tags: ["گوشی", "هوشمند", "تکنولوژی"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "راهنمای خرید لپ‌تاپ مناسب برای دانشجویان",
slug: "laptop-buying-guide-for-students",
category: category._id,
description: "نکاتی که دانشجویان باید هنگام خرید لپ‌تاپ مد نظر داشته باشند.",
content:
"برای دانشجویان، انتخاب لپ‌تاپ مناسب اهمیت زیادی دارد. عواملی مانند وزن، عمر باتری، قدرت پردازش و قیمت باید در نظر گرفته شوند...",
author: admin!._id,
tags: ["لپ‌تاپ", "خرید", "راهنما"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "تکنولوژی‌های نوین در تلویزیون‌های هوشمند",
slug: "innovative-technologies-in-smart-tvs",
category: category._id,
description: "بررسی آخرین تکنولوژی‌های موجود در تلویزیون‌های هوشمند.",
content:
"تلویزیون‌های هوشمند امروزه با تکنولوژی‌های پیشرفته‌ای مانند 4K، OLED، HDR و سیستم‌های هوش مصنوعی مجهز شده‌اند که تجربه تماشای شما را بهبود می‌بخشند...",
author: admin!._id,
tags: ["تلویزیون", "هوشمند", "تکنولوژی"],
imageUrl: fakeImageGenerator(),
view: 0,
},
);
break;
case "fashion":
blogs.push(
{
title_fa: "جدیدترین ترندهای مد بهار ۲۰۲۴",
slug: "latest-spring-fashion-trends-2024",
category: category._id,
description: "مروری بر جدیدترین ترندهای مد فصل بهار ۲۰۲۴.",
content:
"فصل بهار ۲۰۲۴ با ورود رنگ‌های شاد، الگوهای گلدار و پارچه‌های سبک همراه است. این ساله تاکید بیشتری بر روی راحتی و استایل کلاسیک دیده می‌شود...",
author: admin!._id,
tags: ["مد", "بهار", "ترند"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "چگونه لباس مناسب را برای یک مراسم رسمی انتخاب کنیم",
slug: "choosing-suitable-clothes-for-formal-events",
category: category._id,
description: "نکاتی برای انتخاب لباس مناسب جهت شرکت در مراسم‌های رسمی.",
content:
"انتخاب لباس مناسب برای مراسم‌های رسمی می‌تواند تاثیر زیادی بر روی حضور شما داشته باشد. در این مقاله به بررسی نکاتی که باید هنگام انتخاب لباس رسمی در نظر بگیرید می‌پردازیم...",
author: admin!._id,
tags: ["لباس", "رسمی", "راهنما"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "استایل‌های مردانه محبوب در سال ۲۰۲۴",
slug: "popular-mens-fashion-styles-2024",
category: category._id,
description: "بررسی استایل‌های محبوب و جدید در مد مردانه سال ۲۰۲۴.",
content:
"مد مردانه در سال ۲۰۲۴ با ترکیب کلاسیک و مدرن، سبک‌های متنوعی را ارائه می‌دهد. از کت و شلوارهای شیک گرفته تا استایل‌های کژوال و خیابانی، انتخاب‌های زیادی وجود دارد...",
author: admin!._id,
tags: ["مد", "مردانه", "استایل"],
imageUrl: fakeImageGenerator(),
view: 0,
},
);
break;
case "home-kitchen":
blogs.push(
{
title_fa: "بهترین لوازم آشپزخانه برای هر خانه",
slug: "best-kitchen-appliances-for-every-home",
category: category._id,
description: "نکاتی برای انتخاب بهترین لوازم آشپزخانه مناسب برای خانه‌های مختلف.",
content:
"لوازم آشپزخانه نقش مهمی در راحتی و کارایی خانه دارند. از ماشین لباسشویی گرفته تا فرهای هوشمند، انتخاب صحیح می‌تواند تجربه آشپزی شما را بهبود بخشد...",
author: admin!._id,
tags: ["آشپزخانه", "لوازم", "راهنما"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "نکات طراحی داخلی خانه برای فضاهای کوچک",
slug: "interior-design-tips-for-small-spaces",
category: category._id,
description: "راهنمایی‌هایی برای طراحی داخلی مناسب فضاهای کوچک خانه.",
content:
"طراحی داخلی فضاهای کوچک نیازمند استفاده بهینه از فضا و انتخاب مبلمان چندکاره است. در این مقاله به بررسی نکاتی که می‌تواند به شما در طراحی منزل کوچک کمک کند می‌پردازیم...",
author: admin!._id,
tags: ["طراحی داخلی", "خانه کوچک", "نکات"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "روش‌های سازماندهی و بهینه‌سازی فضای آشپزخانه",
slug: "organizing-and-optimizing-kitchen-space",
category: category._id,
description: "نکاتی برای سازماندهی و بهینه‌سازی فضای آشپزخانه.",
content:
"یک آشپزخانه سازماندهی شده نه تنها زیبایی دارد بلکه کارایی بیشتری نیز دارد. از استفاده از کشوهای چندمنظوره تا نگهداری مناسب ابزارهای آشپزی، این مقاله به شما کمک می‌کند تا آشپزخانه‌تان را بهینه کنید...",
author: admin!._id,
tags: ["آشپزخانه", "سازماندهی", "بهینه‌سازی"],
imageUrl: fakeImageGenerator(),
view: 0,
},
);
break;
case "beauty-health":
blogs.push(
{
title_fa: "رازهای داشتن پوستی سالم و درخشان",
slug: "secrets-to-healthy-glowing-skin",
category: category._id,
description: "نکاتی برای داشتن پوستی سالم، درخشان و زیبا.",
content:
"پوستی سالم نیازمند مراقبت‌های منظم و استفاده از محصولات مناسب است. در این مقاله به بررسی رازهایی که می‌تواند به شما کمک کند پوستی درخشان و زیبا داشته باشید می‌پردازیم...",
author: admin!._id,
tags: ["زیبایی", "سلامت پوست", "راهنما"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "فواید ورزش منظم برای سلامت روانی",
slug: "benefits-of-regular-exercise-for-mental-health",
category: category._id,
description: "بررسی فواید ورزش منظم بر سلامت روانی انسان.",
content:
"ورزش نه تنها به بهبود سلامت جسمی کمک می‌کند بلکه تاثیرات مثبت زیادی بر سلامت روانی دارد. از کاهش استرس تا افزایش اعتماد به نفس، در این مقاله به بررسی این فواید می‌پردازیم...",
author: admin!._id,
tags: ["ورزش", "سلامت روان", "فواید"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "مراقبت از موهای خشک و آسیب‌دیده",
slug: "caring-for-dry-damaged-hair",
category: category._id,
description: "نکاتی برای مراقبت و ترمیم موهای خشک و آسیب‌دیده.",
content:
"موهای خشک و آسیب‌دیده نیازمند مراقبت ویژه‌ای هستند. از استفاده از شامپوهای مرطوب‌کننده تا ماسک‌های تغذیه‌کننده، در این مقاله به بررسی روش‌هایی که می‌تواند به ترمیم و تقویت موهای شما کمک کند می‌پردازیم...",
author: admin!._id,
tags: ["مو", "زیبایی", "مراقبت"],
imageUrl: fakeImageGenerator(),
view: 0,
},
);
break;
case "gaming-entertainment":
blogs.push(
{
title_fa: "پربازترین بازی‌های ویدیویی سال ۲۰۲۴",
slug: "most-played-video-games-2024",
category: category._id,
description: "مروری بر پربازترین و محبوب‌ترین بازی‌های ویدیویی عرضه شده در سال ۲۰۲۴.",
content:
"سال ۲۰۲۴ با عرضه بازی‌های ویدیویی هیجان‌انگیزی همراه بوده است. از بازی‌های اکشن گرفته تا RPGها، این مقاله به معرفی پربازترین و محبوب‌ترین بازی‌های سال می‌پردازد...",
author: admin!._id,
tags: ["بازی", "ویدیوئی", "مرور"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "نکاتی برای بهبود مهارت‌های بازی‌های رقابتی",
slug: "tips-to-improve-competitive-gaming-skills",
category: category._id,
description: "راهنمایی‌هایی برای ارتقاء مهارت‌ها و موفقیت در بازی‌های رقابتی.",
content:
"بازی‌های رقابتی نیازمند تمرین مداوم و استراتژی‌های هوشمندانه هستند. در این مقاله به بررسی نکاتی می‌پردازیم که می‌تواند به شما کمک کند مهارت‌های بازی رقابتی خود را بهبود ببخشید...",
author: admin!._id,
tags: ["بازی", "رقابتی", "مهارت"],
imageUrl: fakeImageGenerator(),
view: 0,
},
{
title_fa: "بررسی جدیدترین کنسول‌های بازی",
slug: "review-of-latest-gaming-consoles",
category: category._id,
description: "مروری بر جدیدترین کنسول‌های بازی و ویژگی‌های آن‌ها.",
content:
"کنسول‌های بازی جدید با تکنولوژی‌های پیشرفته‌ای عرضه شده‌اند که تجربه بازی را به سطح بالاتری می‌برند. در این مقاله به بررسی ویژگی‌ها و عملکرد جدیدترین کنسول‌های بازی می‌پردازیم...",
author: admin!._id,
tags: ["کنسول", "بازی", "مرور"],
imageUrl: fakeImageGenerator(),
view: 0,
},
);
break;
default:
console.warn(`No seeder defined for category slug: ${category.slug}`);
break;
}
});
// Insert Blogs
await BlogModel.insertMany(blogs);
logger.info("Blogs seeded successfully");
} catch (error) {
logger.error("Error seeding blogs:", error);
}
};
+138
View File
@@ -0,0 +1,138 @@
import { Types } from "mongoose";
import { StatusEnum } from "../../common/enums/status.enum";
import { Logger } from "../../core/logging/logger";
import { BrandModel } from "../../modules/brand/models/brand.model";
import { CategoryModel } from "../../modules/category/models/category.model";
interface IBrandSeed {
title_fa: string;
title_en: string;
// category: Types.ObjectId;
}
const brandSeedMap: { [key: string]: IBrandSeed[] } = {
"گوشی موبایل": [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "اپل", title_en: "Apple" },
{ title_fa: "شیائومی", title_en: "Xiaomi" },
{ title_fa: "هواوی", title_en: "Huawei" },
{ title_fa: "نوکیا", title_en: "Nokia" },
],
تبلت: [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "اپل", title_en: "Apple" },
{ title_fa: "مایکروسافت", title_en: "Microsoft" },
{ title_fa: "لنوو", title_en: "Lenovo" },
{ title_fa: "هواوی", title_en: "Huawei" },
],
"خودکار و خودنویس": [
{ title_fa: "پایلوت", title_en: "Pilot" },
{ title_fa: "شیفر", title_en: "Sheaffer" },
{ title_fa: "پارکر", title_en: "Parker" },
{ title_fa: "لامی", title_en: "Lamy" },
],
لامپ: [
{ title_fa: "فیلیپس", title_en: "Philips" },
{ title_fa: "شیائومی", title_en: "Xiaomi" },
{ title_fa: "اپتونیک", title_en: "Optonique" },
{ title_fa: "نورکالا", title_en: "NoorKala" },
],
اسپیکر: [
{ title_fa: "جی بی ال", title_en: "JBL" },
{ title_fa: "سونی", title_en: "Sony" },
],
تلویزیون: [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "ال جی", title_en: "LG" },
{ title_fa: "سونی", title_en: "Sony" },
{ title_fa: "پاناسونیک", title_en: "Panasonic" },
],
"دوربین عکاسی": [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "ال جی", title_en: "LG" },
{ title_fa: "سونی", title_en: "Sony" },
{ title_fa: "پاناسونیک", title_en: "Nikon" },
],
"ساعت هوشمند": [
{ title_fa: "شیائومی", title_en: "Xiaomi" },
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "اپل", title_en: "Apple" },
{ title_fa: "هواوی", title_en: "Huawei" },
],
هدفون: [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "ال جی", title_en: "LG" },
{ title_fa: "سونی", title_en: "Sony" },
{ title_fa: "بوز", title_en: "Bose" },
],
"پاور بانک": [
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "آنکر", title_en: "Anker" },
],
"لپ تاپ": [
{ title_fa: "ایسر", title_en: "Acer" },
{ title_fa: "ایسوس", title_en: "Asus" },
{ title_fa: "اپل", title_en: "Apple" },
{ title_fa: "لنوو", title_en: "Lenovo" },
],
"لباس زنانه": [
{ title_fa: "زارا", title_en: "Zara" },
{ title_fa: "H&M", title_en: "H&M" },
{ title_fa: "گوچی", title_en: "Gucci" },
{ title_fa: "دیور", title_en: "Dior" },
],
"لوازم آشپزخانه": [
{ title_fa: "بوش", title_en: "Bosch" },
{ title_fa: "فیلیپس", title_en: "Philips" },
{ title_fa: "سامسونگ", title_en: "Samsung" },
{ title_fa: "پاناسونیک", title_en: "Panasonic" },
{ title_fa: "ال جی", title_en: "LG" },
],
"پلی استیشن": [{ title_fa: "سونی", title_en: "Sony" }],
متفرقه: [{ title_fa: "متفرقه", title_en: "malicious" }],
};
export const seedBrands = async (logger: Logger) => {
try {
logger.info("Brands seeding started");
const categoryMap: { [key: string]: Types.ObjectId } = {};
// Fetch all categories once
const categories = await CategoryModel.find();
categories.forEach((category) => {
categoryMap[category.title_fa] = category._id;
});
const brandDocuments = [];
// Prepare brand documents in bulk
for (const [categoryTitle, brands] of Object.entries(brandSeedMap)) {
const categoryId = categoryMap[categoryTitle];
if (categoryId) {
for (const brand of brands) {
const { title_fa, title_en } = brand;
brandDocuments.push({
title_fa,
title_en,
category: categoryId,
status: StatusEnum.Approved,
});
}
} else {
logger.warn(`Category '${categoryTitle}' not found`);
}
}
// Bulk insert
if (brandDocuments.length > 0) {
await BrandModel.insertMany(brandDocuments);
}
logger.info("Brands seeded successfully");
} catch (error) {
logger.error("Error seeding brands:", error);
}
};
+98
View File
@@ -0,0 +1,98 @@
import { Logger } from "../../core/logging/logger";
import { ColorModel } from "../../modules/category/models/color.model";
import { MeterageModel } from "../../modules/category/models/meterage.model";
import { SizeModel } from "../../modules/category/models/size.model";
const colors = [
{ name: "قرمز", hexColor: "#FF0000" },
{ name: "سبز", hexColor: "#00FF00" },
{ name: "آبی", hexColor: "#0000FF" },
{ name: "مشکی", hexColor: "#000000" },
{ name: "سفید", hexColor: "#FFFFFF" },
{ name: "زرد", hexColor: "#FFFF00" },
{ name: "بنفش", hexColor: "#800080" },
{ name: "نارنجی", hexColor: "#FFA500" },
{ name: "صورتی", hexColor: "#FFC0CB" },
{ name: "خاکستری", hexColor: "#808080" },
];
const sizes = [
{ value: "XS" },
{ value: "S" },
{ value: "M" },
{ value: "L" },
{ value: "XL" },
{ value: "XXL" },
{ value: "3XL" },
{ value: "4XL" },
{ value: "5XL" },
{ value: "6XL" },
];
const meterages = [
{ value: "1" },
{ value: "2" },
{ value: "3" },
{ value: "4" },
{ value: "5" },
{ value: "10" },
{ value: "15" },
{ value: "20" },
{ value: "25" },
{ value: "30" },
];
const seedColors = async () => {
try {
console.log("Seeding colors...");
await ColorModel.deleteMany({});
for (const color of colors) {
await ColorModel.create(color);
}
console.log("Colors seeded successfully");
} catch (error) {
console.error("Error seeding colors:", error);
}
};
const seedSizes = async () => {
try {
console.log("Seeding sizes...");
await SizeModel.deleteMany({});
for (const size of sizes) {
await SizeModel.create(size);
}
console.log("Sizes seeded successfully");
} catch (error) {
console.error("Error seeding sizes:", error);
}
};
const seedMeterages = async () => {
try {
console.log("Seeding meterages...");
await MeterageModel.deleteMany({});
for (const meterage of meterages) {
await MeterageModel.create(meterage);
}
console.log("Meterages seeded successfully");
} catch (error) {
console.error("Error seeding meterages:", error);
}
};
// Seed function
export const seedCatVariant = async (logger: Logger) => {
try {
logger.info("Categories variant seeding started");
await seedColors();
await seedSizes();
await seedMeterages();
console.log("Seeding complete!");
} catch (error) {
logger.error("Seeding error:", error);
}
};
+556
View File
@@ -0,0 +1,556 @@
import { faker } from "@faker-js/faker";
import { Types } from "mongoose";
faker.locale = "fa";
import { CategoryThemeEnum } from "../../common/enums/category.enum";
import { Logger } from "../../core/logging/logger";
import { AttributeValueModel } from "../../modules/category/models/attributeValue.model";
import { CategoryModel } from "../../modules/category/models/category.model";
import { CategoryAttributeModel } from "../../modules/category/models/CategoryAttribute.model";
import { ColorModel } from "../../modules/category/models/color.model";
import { MeterageModel } from "../../modules/category/models/meterage.model";
import { SizeModel } from "../../modules/category/models/size.model";
interface ICategorySeed {
title_fa: string;
title_en: string;
icon: string;
imageUrl: string;
description: string;
leaf: boolean;
theme?: CategoryThemeEnum;
parent?: Types.ObjectId;
}
interface ICategoryAttributeSeed {
title: string;
hint?: string;
type: string;
multiple: boolean;
required: boolean;
}
const rootCategories: ICategorySeed[] = [
{
title_fa: "موبایل و تبلت",
icon: "mobile",
imageUrl: faker.image.imageUrl(),
description: "لوازم جانبی",
title_en: "mobile",
leaf: false,
},
{
title_fa: "لوازم تحریر و اداری",
icon: "stationery",
description: "انواع لوازم تحریر و اداری",
title_en: "stationery-office",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "برق و الکتریکی",
icon: "electric",
description: "لوازم برق و الکتریکی",
title_en: "electric-electrical",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "لوازم و ابزارآلات",
icon: "tools",
description: "انواع لوازم و ابزارآلات",
title_en: "tools-equipment",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "صوت و تصویر",
icon: "audio-visual",
description: "انواع لوازم صوتی و تصویری",
title_en: "audio-visual",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "کامپیوتر",
icon: "computer",
description: "انواع کامپیوتر و لوازم جانبی",
title_en: "computer",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "کنسول بازی",
icon: "console",
description: "انواع کنسول بازی و لوازم جانبی",
title_en: "game-console",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "ورزش و سفر",
icon: "sports",
description: "لوازم ورزشی و سفر",
title_en: "sports-travel",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{ title_fa: "پوشاک و مد", icon: "fashion", description: "لباس و مد", title_en: "fashion", leaf: false, imageUrl: faker.image.imageUrl() },
{
title_fa: "لوازم خانگی",
icon: "home-appliances",
description: "لوازم خانه",
title_en: "home-appliances",
leaf: false,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "متفرقه",
icon: "malicious",
description: "متفرقه",
title_en: "malicious",
leaf: true,
imageUrl: faker.image.imageUrl(),
},
];
const subcategories: { [key: string]: ICategorySeed[] } = {
"موبایل و تبلت": [
{
title_fa: "گوشی موبایل",
icon: "phone",
description: "انواع گوشی های موبایل",
title_en: "mobile-phones",
leaf: true,
imageUrl: faker.image.imageUrl(),
theme: CategoryThemeEnum.Colored,
},
{
title_fa: "تبلت",
icon: "tablet",
description: "انواع تبلت ها",
title_en: "tablets",
leaf: true,
theme: CategoryThemeEnum.Colored,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "ساعت هوشمند",
icon: "watch",
description: "انواع ساعت هوشمند",
title_en: "smart-watch",
leaf: true,
theme: CategoryThemeEnum.Colored,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "پاور بانک",
icon: "watch",
description: "انواع پاور بانک",
title_en: "power-banks",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"لوازم تحریر و اداری": [
{
title_fa: "خودکار و خودنویس",
icon: "pen",
description: "انواع خودکار و خودنویس",
title_en: "pens",
leaf: true,
theme: CategoryThemeEnum.Colored,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "دفتر و کاغذ",
icon: "paper",
description: "انواع دفتر و کاغذ",
title_en: "paper-notebooks",
leaf: true,
theme: CategoryThemeEnum.Colored,
imageUrl: faker.image.imageUrl(),
},
],
"برق و الکتریکی": [
{
title_fa: "لامپ",
icon: "bulb",
description: "انواع لامپ ها",
title_en: "bulbs",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "کابل و سیم",
icon: "cable",
description: "انواع کابل و سیم",
title_en: "cables-wires",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"لوازم و ابزارآلات": [
{
title_fa: "آچار و پیچ گوشتی",
icon: "wrench",
description: "انواع آچار و پیچ گوشتی",
title_en: "wrenches-screwdrivers",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "دریل",
icon: "drill",
description: "انواع دریل ها",
title_en: "drills",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"صوت و تصویر": [
{
title_fa: "تلویزیون",
icon: "tv",
description: "انواع تلویزیون",
title_en: "televisions",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "اسپیکر",
icon: "speaker",
description: "انواع اسپیکر",
title_en: "speakers",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "هدفون",
icon: "headphone",
description: "انواع هدفون",
title_en: "headphones",
leaf: true,
theme: CategoryThemeEnum.Colored,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "دوربین عکاسی",
icon: "camera",
description: "انواع دوربین عکاسی",
title_en: "cameras",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
کامپیوتر: [
{
title_fa: "لپ تاپ",
icon: "laptop",
description: "انواع لپ تاپ",
title_en: "laptops",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "موس و کیبورد",
icon: "mouse-keyboard",
description: "انواع موس و کیبورد",
title_en: "mouse-keyboards",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"کنسول بازی": [
{
title_fa: "پلی استیشن",
icon: "playstation",
description: "انواع پلی استیشن",
title_en: "playstations",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "ایکس باکس",
icon: "xbox",
description: "انواع ایکس باکس",
title_en: "xbox",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"ورزش و سفر": [
{
title_fa: "تجهیزات ورزشی",
icon: "sports-equipment",
description: "انواع تجهیزات ورزشی",
title_en: "sports-equipment",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "لوازم سفر",
icon: "travel",
description: "انواع لوازم سفر",
title_en: "travel-equipment",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
"پوشاک و مد": [
{
title_fa: "لباس زنانه",
icon: "women-clothing",
description: "انواع لباس زنانه",
title_en: "women-clothing",
leaf: true,
theme: CategoryThemeEnum.Sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "لباس مردانه",
icon: "men-clothing",
description: "انواع لباس مردانه",
title_en: "men-clothing",
leaf: true,
theme: CategoryThemeEnum.Sized,
imageUrl: faker.image.imageUrl(),
},
],
"لوازم خانگی": [
{
title_fa: "لوازم آشپزخانه",
icon: "kitchen-appliances",
description: "انواع لوازم آشپزخانه",
title_en: "kitchen-appliances",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
{
title_fa: "لوازم نظافت",
icon: "cleaning-appliances",
description: "انواع لوازم نظافت",
title_en: "cleaning-appliances",
leaf: true,
theme: CategoryThemeEnum.No_color_No_sized,
imageUrl: faker.image.imageUrl(),
},
],
};
const categoryAttributesMap: { [key: string]: ICategoryAttributeSeed[] } = {
"گوشی موبایل": [
{ title: "باتری", hint: "ظرفیت باتری", type: "select", multiple: false, required: true },
{ title: "دوربین", hint: "کیفیت دوربین", type: "select", multiple: false, required: true },
{ title: "سیستم عامل", hint: "نوع سیستم عامل", type: "select", multiple: false, required: true },
{ title: "حافظه داخلی موبایل", hint: "ظرفیت حافظه", type: "select", multiple: false, required: true },
{ title: "پشتیبانی از 5G", hint: "آیا پشتیبانی می‌کند؟", type: "checkbox", multiple: false, required: false },
],
تبلت: [
{ title: "اندازه صفحه تبلت", hint: "اینچ", type: "select", multiple: false, required: true },
{ title: "پردازنده تبلت", hint: "نوع پردازنده", type: "select", multiple: false, required: true },
{ title: "دوربین جلو", hint: "کیفیت دوربین جلو", type: "select", multiple: false, required: false },
{ title: "ظرفیت باتری", hint: "میلی‌آمپر ساعت", type: "select", multiple: false, required: true },
{ title: "اتصال به شبکه", hint: "نوع شبکه", type: "select", multiple: false, required: false },
],
"خودکار و خودنویس": [
{ title: "نوع جوهر", hint: "جوهر مورد استفاده", type: "select", multiple: false, required: true },
{ title: "ضخامت نوشتاری", hint: "ضخامت نوک", type: "select", multiple: false, required: true },
{ title: "قابلیت شارژ مجدد", hint: "آیا قابل شارژ است؟", type: "checkbox", multiple: false, required: false },
{ title: "جنس بدنه خودکار", hint: "جنس بدنه خودکار", type: "select", multiple: false, required: true },
{ title: "رنگ جوهر", hint: "رنگ جوهر خودکار", type: "select", multiple: false, required: true },
],
لامپ: [
{ title: "نوع لامپ", hint: "نوع لامپ (LED، هالوژن و غیره)", type: "select", multiple: false, required: true },
{ title: "توان مصرفی لامپ", hint: "وات", type: "select", multiple: false, required: true },
{ title: "رنگ نور", hint: "رنگ نور", type: "select", multiple: false, required: true },
{ title: "طول عمر", hint: "ساعت", type: "select", multiple: false, required: true },
{ title: "قابلیت تنظیم شدت نور", hint: "آیا قابل تنظیم است؟", type: "checkbox", multiple: false, required: false },
],
تلویزیون: [
{ title: "اندازه صفحه تلویزیون", hint: "اینچ", type: "select", multiple: false, required: true },
{ title: "رزولوشن", hint: "کیفیت تصویر", type: "select", multiple: false, required: true },
{ title: "نوع صفحه", hint: "LED, OLED, QLED", type: "select", multiple: false, required: true },
{ title: "هوشمند", hint: "آیا هوشمند است؟", type: "checkbox", multiple: false, required: false },
{ title: "درگاه‌های ارتباطی", hint: "نوع و تعداد درگاه‌ها", type: "select", multiple: true, required: true },
],
"لپ تاپ": [
{ title: "پردازنده لپ تاپ", hint: "نوع پردازنده", type: "select", multiple: false, required: true },
{ title: "حافظه رم", hint: "ظرفیت حافظه رم", type: "select", multiple: false, required: true },
{ title: "حافظه داخلی", hint: "ظرفیت حافظه", type: "select", multiple: false, required: true },
{ title: "اندازه صفحه", hint: "اینچ", type: "select", multiple: false, required: true },
{ title: "کارت گرافیک", hint: "نوع کارت گرافیک", type: "select", multiple: false, required: true },
],
"لباس زنانه": [
{ title: "جنس پارچه", hint: "نوع پارچه", type: "select", multiple: false, required: true },
{ title: "نوع یقه", hint: "یقه لباس", type: "select", multiple: false, required: true },
{ title: "نوع آستین", hint: "آستین لباس", type: "select", multiple: false, required: true },
{ title: "مدل لباس", hint: "نوع و مدل لباس", type: "select", multiple: false, required: true },
{ title: "نوع شستشو", hint: "نحوه شستشو", type: "select", multiple: false, required: false },
],
"لوازم آشپزخانه": [
{ title: "توان مصرفی", hint: "توان لوازم برقی", type: "select", multiple: false, required: true },
{ title: "جنس بدنه", hint: "جنس بدنه دستگاه", type: "select", multiple: false, required: true },
{ title: "ظرفیت", hint: "ظرفیت دستگاه", type: "select", multiple: false, required: true },
{ title: "قابلیت تنظیم", hint: "آیا قابلیت تنظیم دارد؟", type: "checkbox", multiple: false, required: false },
{ title: "نوع کاربری", hint: "کاربری دستگاه", type: "select", multiple: false, required: true },
],
// Add more categories as needed
};
const attributeValuesMap: { [key: string]: string[] } = {
باتری: ["3000mAh", "4000mAh", "5000mAh", "6000mAh", "7000mAh"],
دوربین: ["12MP", "16MP", "20MP", "48MP", "108MP"],
"سیستم عامل": ["اندروید", "iOS", "ویندوز", "لینوکس", "سایر"],
"حافظه داخلی موبایل": ["32GB", "64GB", "128GB", "256GB", "512GB"],
"پشتیبانی از 5G": ["بله", "خیر"],
"اندازه صفحه تبلت": ["7 اینچ", "10 اینچ", "13 اینچ", "15 اینچ", "17 اینچ"],
"پردازنده تبلت": ["Intel", "AMD", "Apple M1", "Qualcomm", "MediaTek"],
"دوربین جلو": ["5MP", "8MP", "12MP", "16MP", "20MP"],
"ظرفیت باتری": ["2000mAh", "3000mAh", "4000mAh", "5000mAh", "6000mAh"],
"اتصال به شبکه": ["WiFi", "4G", "5G", "Ethernet", "بلوتوث"],
"نوع جوهر": ["ژل", "روغنی", "آبی", "خودکار", "پلاستیکی"],
"ضخامت نوشتاری": ["0.5mm", "0.7mm", "1.0mm", "1.2mm", "1.5mm"],
"قابلیت شارژ مجدد": ["بله", "خیر"],
"جنس بدنه خودکار": ["فلز", "پلاستیک", "چوب", "سرامیک", "کربن"],
"رنگ جوهر": ["مشکی", "آبی", "قرمز", "سبز", "بنفش"],
"نوع لامپ": ["LED", "هالوژن", "فلورسنت", "رشته‌ای", "پلاسما"],
"توان مصرفی لامپ": ["5W", "10W", "15W", "20W", "25W"],
"رنگ نور": ["سفید", "زرد", "آبی", "سبز", "قرمز"],
"طول عمر": ["1000 ساعت", "5000 ساعت", "10000 ساعت", "20000 ساعت", "50000 ساعت"],
"قابلیت تنظیم شدت نور": ["بله", "خیر"],
"اندازه صفحه تلویزیون": ["20 اینچ", "32 اینچ", "40 اینچ", "60 اینچ", "70 اینچ"],
رزولوشن: ["720p", "1080p", "4K", "8K", "HDR"],
"نوع صفحه": ["LED", "OLED", "QLED", "Plasma", "LCD"],
هوشمند: ["بله", "خیر"],
"درگاه‌های ارتباطی": ["HDMI", "USB", "Bluetooth", "WiFi", "Ethernet"],
"پردازنده لپ تاپ": ["Intel", "AMD", "Apple M1", "Qualcomm", "Apple M2"],
"حافظه رم": ["4GB", "8GB", "16GB", "32GB", "64GB"],
"حافظه داخلی": ["128GB", "256GB", "512GB", "1TB"],
"اندازه صفحه": ["14 اینچ", "12 اینچ", "16 اینچ"],
"کارت گرافیک": ["NVIDIA", "AMD", "Intel", "Apple M1", "ARM Mali"],
"جنس پارچه": ["پنبه", "پلی‌استر", "نایلون", "ریون", "کتان"],
"نوع یقه": ["گرد", "هفت", "ایستاده", "دکمه‌ای", "یقه اسکی"],
"نوع آستین": ["کوتاه", "بلند", "سه‌ربع", "بی‌آستین", "کشباف"],
"مدل لباس": ["تی‌شرت", "پیراهن", "ژاکت", "هودی", "پلیور"],
"نوع شستشو": ["ماشینی", "دستی", "خشک‌شویی", "آب سرد", "آب گرم"],
"توان مصرفی": ["150W", "200W", "400W"],
"جنس بدنه": ["فلز", "پلاستیک", "چوب", "سرامیک", "کربن"],
ظرفیت: ["1 لیتر", "2 لیتر", "3 لیتر", "4 لیتر", "5 لیتر"],
"قابلیت تنظیم": ["بله", "خیر"],
"نوع کاربری": ["آبمیوه‌گیری", "مخلوط‌کن", "آسیاب", "کباب‌پز", "زودپز"],
// Add more attributes and their values as needed
};
export const seedCategories = async (logger: Logger) => {
try {
logger.info("Categories seeding started");
const colors = (await ColorModel.find()).map((color) => color._id);
const sizes = (await SizeModel.find()).map((size) => size._id);
const meterages = (await MeterageModel.find()).map((meterage) => meterage._id);
const createdCategories: { [key: string]: Types.ObjectId } = {};
const createdSubCategories: { [key: string]: Types.ObjectId } = {};
// Create root categories
for (const category of rootCategories) {
const { title_fa, icon, description, title_en, leaf, imageUrl } = category;
const rootCategory = new CategoryModel({ title_fa, icon, title_en, description, leaf, imageUrl });
await rootCategory.save();
createdCategories[title_fa] = rootCategory._id;
}
// Create subcategories
for (const [rootName, subs] of Object.entries(subcategories)) {
const parentId = createdCategories[rootName];
if (parentId) {
for (const subcategory of subs) {
const { title_fa, icon, description, title_en, leaf, theme, imageUrl } = subcategory;
const catVariants =
theme === CategoryThemeEnum.Colored
? [...colors]
: theme === CategoryThemeEnum.Meterage
? [...meterages]
: theme === CategoryThemeEnum.Sized
? [...sizes]
: [];
const subCategoryDoc = new CategoryModel({
title_fa,
icon,
imageUrl,
title_en,
description,
leaf,
theme,
variants: catVariants,
parent: parentId,
});
await subCategoryDoc.save();
// Save the subcategory ID for later use
createdSubCategories[title_fa] = subCategoryDoc._id;
}
}
}
const createdAttributes: { [key: string]: number } = {};
// Generate attributes for each subcategory
for (const [subcategoryTitle, attributes] of Object.entries(categoryAttributesMap)) {
const subcategoryId = createdSubCategories[subcategoryTitle];
if (subcategoryId) {
for (const attr of attributes) {
const attributeDoc = new CategoryAttributeModel({
category: subcategoryId,
title: attr.title,
hint: attr.hint,
type: attr.type,
multiple: attr.multiple,
required: attr.required,
});
await attributeDoc.save();
createdAttributes[attr.title] = attributeDoc._id;
}
} else {
logger.warn(`Subcategory '${subcategoryTitle}' not found.`);
}
}
// Generate values for each attribute
for (const [attributeTitle, attributeId] of Object.entries(createdAttributes)) {
const values = attributeValuesMap[attributeTitle] || [];
for (const valueText of values) {
await AttributeValueModel.create({
attribute: attributeId,
text: valueText,
});
// await valueDoc.save();
}
}
logger.info("Categories, subcategories, attributes, and values seeded successfully");
} catch (error) {
logger.error("Error seeding categories:", error);
}
};
+17
View File
@@ -0,0 +1,17 @@
import { Logger } from "../../core/logging/logger";
import { ContractModel } from "../../modules/admin/models/contract.model";
export const contractSeeder = async (logger: Logger) => {
try {
const existContract = await ContractModel.exists({});
if (existContract) return;
await ContractModel.create({
content: "متن قرار داد را اینجا قرار دهید",
});
logger.info("Contract collection seeded!");
} catch (error) {
logger.error("Contract collection seed failed!", error);
}
};
+68
View File
@@ -0,0 +1,68 @@
import { Logger } from "../../core/logging/logger";
import { PermissionEnum } from "../../modules/admin/models/Abstraction/IPermission";
import { RoleEnum } from "../../modules/admin/models/Abstraction/IRole";
import { AdminModel } from "../../modules/admin/models/admin.model";
import { PermissionModel } from "../../modules/admin/models/permission.model";
import { RoleModel } from "../../modules/admin/models/role.model";
import { ShipmentModel } from "../../modules/shipment/models/shipment.model";
import { OwnerRef } from "../../modules/shop/models/Abstraction/IShop";
import { ShopModel } from "../../modules/shop/models/shop.model";
const createDefaultAdmin = async (logger: Logger) => {
logger.info("createDefaultAdmin started", "SEED");
const email = process.env.DEFAULT_ADMIN_EMAIL;
const password = process.env.DEFAULT_ADMIN_PASSWORD;
if (!email || !password) {
throw new Error("Default admin credentials are not set in the environment variables");
}
// Create permissions based on the enum
const permissions = Object.values(PermissionEnum);
const createdPermissions = await Promise.all(
permissions.map(async (perm) => {
const existingPermission = await PermissionModel.findOne({ name: perm });
if (!existingPermission) {
return PermissionModel.create({ name: perm });
}
return existingPermission;
}),
);
// create or find the SUPERADMIN role
let superAdminRole = await RoleModel.findOne({ name: RoleEnum.SUPERADMIN });
if (!superAdminRole) {
superAdminRole = await RoleModel.create({
name: RoleEnum.SUPERADMIN,
});
logger.info("SUPERADMIN role created", "SEED");
} else {
logger.warn("SUPERADMIN role already exists", "SEED");
}
let admin = await AdminModel.findOne({ email });
if (!admin) {
admin = await AdminModel.create({
email,
password,
fullName: "defaultAdmin",
userName: "defaultAdmin",
permissions: createdPermissions.map((perm) => perm._id),
role: superAdminRole._id,
});
const shipments = (await ShipmentModel.find()).map((shipper) => shipper._id);
await ShopModel.create({
owner: admin._id.toString(),
ownerRef: OwnerRef.ADMIN,
shipmentMethod: shipments,
shopDescription: "فروشگاه شینان",
shopName: "شینان",
});
logger.info("Default admin user and native shop created", "SEED");
} else {
logger.warn("Default admin user and native shop already exists", "SEED");
}
};
export { createDefaultAdmin };
+36
View File
@@ -0,0 +1,36 @@
import { Logger } from "../../core/logging/logger";
import { FaqModel } from "../../modules/faq/models/faq.model";
export const seedFaqs = async (logger: Logger) => {
try {
logger.info("start seeding the FAQ");
const faqs = [
{
question: "چگونه میتوانم سفارش خود را پیگیری کنم؟",
answer: "برای پیگیری سفارش خود، می‌توانید به حساب کاربری خود وارد شوید و از قسمت سفارشات من، وضعیت سفارش خود را مشاهده کنید.",
},
{
question: "آیا امکان بازگشت کالا وجود دارد؟",
answer: "بله، در صورت داشتن شرایط بازگشت، می‌توانید کالا را تا ۷ روز پس از تحویل بازگردانید.",
},
{
question: "چگونه میتوانم حساب کاربری ایجاد کنم؟",
answer: "برای ایجاد حساب کاربری، کافیست در صفحه اصلی سایت به قسمت ثبت نام مراجعه کرده و اطلاعات خود را وارد کنید.",
},
{
question: "روش‌های پرداخت چگونه است؟",
answer: "پرداخت‌ها می‌تواند از طریق کارت‌های شتاب، درگاه‌های بانکی و پرداخت در محل انجام شود.",
},
{
question: "چگونه میتوانم از کد تخفیف استفاده کنم؟",
answer: "هنگام پرداخت، در قسمت کد تخفیف، کد خود را وارد کنید و سپس دکمه اعمال را بزنید.",
},
];
await FaqModel.insertMany(faqs);
logger.info("FAQ data seeded successfully");
} catch (error) {
logger.error("Error seeding FAQ data:", error);
}
};
+62
View File
@@ -0,0 +1,62 @@
import "reflect-metadata";
import { config } from "dotenv";
config();
import mongoose from "mongoose";
import { Logger } from "../../core/logging/logger";
import { connectMongo } from "../connection";
// import { backfillHierarchy } from "./backfillHierarchy";
import { blogCategorySeeder } from "./blogCategorySeeder";
import { blogSeeder } from "./blogSeeder";
import { contractSeeder } from "./contractSeeder";
// import { seedMedia } from "./mediaSeeder";
import { seedCityAndProvince } from "./iranCityseeder";
import { SeedPricing } from "./pricingSeeder";
import { clearDatabase } from "../clearDatabase";
import { backfillHierarchy } from "./backfillHierarchy";
import { createDefaultAdmin } from "./defaultAdmin";
import { seedFaqs } from "./faqSeeder";
import { seedMedia } from "./mediaSeeder";
import { seedPaymentMethods } from "./pgSeeder";
import { ReportQuesSeeder } from "./reportQuestion";
import { createDefaultRoles } from "./roleSeeder";
import { SeedShipment } from "./shipmentSeeder";
import { seedTicketCategories } from "./ticketSeeder";
import { seedWarranty } from "./warrantySeeders";
const logger = new Logger("Seeder");
const seedDatabase = async () => {
try {
await connectMongo();
logger.info("connected to mongodb");
await clearDatabase(logger);
await backfillHierarchy();
await blogCategorySeeder(logger);
await blogSeeder(logger);
await contractSeeder(logger);
await createDefaultAdmin(logger);
await seedFaqs(logger);
await seedCityAndProvince(logger);
await SeedPricing(logger);
await seedMedia(logger);
await seedPaymentMethods(logger);
await ReportQuesSeeder(logger);
await createDefaultRoles(logger);
await SeedShipment(logger);
await seedTicketCategories(logger);
await seedWarranty(logger);
logger.info("Seeding completed");
process.exit(0);
} catch (error) {
//
console.error("Error during seeding:", error);
logger.error("Error during seeding:", error);
process.exit(1);
} finally {
//
await mongoose.connection.close();
}
};
seedDatabase();
+39
View File
@@ -0,0 +1,39 @@
import { Logger } from "../../core/logging/logger";
import { CityModel } from "../../modules/address/models/city.model";
import { ProvinceModel } from "../../modules/address/models/province.model";
import province from "../data/json/ostan.json";
import city from "../data/json/shahr.json";
interface IProvince {
id: number;
name: string;
}
interface ICities extends IProvince {
ostan: number;
}
const provinces: IProvince[] = province;
const cities: ICities[] = city;
export const seedCityAndProvince = async (logger: Logger) => {
try {
logger.info("start seeding the city and province", "SEED");
for (const province of provinces) {
await ProvinceModel.create({
name: province.name,
});
}
for (const city of cities) {
await CityModel.create({
name: city.name,
province: city.ostan,
});
}
logger.info("city and province seeding completed", "SEED");
} catch (error) {
logger.error("error in seeding the city and province", error);
}
};
+46
View File
@@ -0,0 +1,46 @@
import { Logger } from "../../core/logging/logger";
import { JobType } from "../../modules/job/models/Abstraction/IJob";
import { JobModel } from "../../modules/job/models/job.model";
export const seedJobs = async (logger: Logger) => {
const jobs = [
{
title: "برنامه‌نویس وب",
description: "ما به دنبال یک برنامه‌نویس وب با تجربه در React و Node.js هستیم.",
location: "تهران",
type: JobType.FullTime,
},
{
title: "طراح UI/UX",
description: "نیازمند یک طراح UI/UX با تجربه برای بهبود تجربه کاربری وب‌سایت هستیم.",
location: "اصفهان",
type: JobType.Contract,
},
{
title: "کارشناس فروش",
description: "به یک کارشناس فروش برای توسعه بازار و جذب مشتری نیازمندیم.",
location: "شیراز",
type: JobType.PartTime,
},
{
title: "مدیر پروژه",
description: "نیازمند مدیر پروژه‌ای با تجربه در مدیریت تیم‌های فنی برای مدیریت پروژه‌های IT.",
location: "مشهد",
type: JobType.FullTime,
},
{
title: "تحلیل‌گر داده",
description: "به یک تحلیل‌گر داده برای تحلیل و بررسی داده‌های شرکت نیاز داریم.",
location: "تبریز",
type: JobType.Contract,
},
];
try {
logger.info("start seeding the jobs");
await JobModel.insertMany(jobs);
logger.info("Job seeding completed!");
} catch (error) {
logger.error("Job seeding failed: ", error);
}
};
+193
View File
@@ -0,0 +1,193 @@
import { Logger } from "../../core/logging/logger";
import { BannerModel } from "../../modules/admin/models/media.model";
export async function seedMedia(logger: Logger) {
try {
// await SliderModel.deleteMany({});
// await BannerModel.deleteMany({});
// logger.info("Cleared existing data");
// // Seed Sliders
// const sliders = [
// {
// displayLocation: DisplayLocations.Mobile,
// imageUrl: "https://loremflickr.com/1920/1080",
// altText: "اسلایدر ۱",
// title: "خوش آمدید به اسلایدر ۱",
// linkUrl: "/slider1",
// isActive: true,
// },
// {
// displayLocation: DisplayLocations.Mobile,
// imageUrl: "https://loremflickr.com/1920/1080",
// altText: "اسلایدر ۲",
// title: "اسلایدر ۲ را کشف کنید",
// linkUrl: "/slider2",
// isActive: true,
// },
// {
// displayLocation: DisplayLocations.Desktop,
// imageUrl: "https://loremflickr.com/1920/1080",
// altText: "اسلایدر ۳",
// title: "بیشتر درباره اسلایدر ۳ بدانید",
// linkUrl: "/slider3",
// isActive: true,
// },
// {
// displayLocation: DisplayLocations.Desktop,
// imageUrl: "https://loremflickr.com/1920/1080",
// altText: "اسلایدر ۴",
// title: "اسلایدر جدید و جذاب",
// linkUrl: "/slider4",
// isActive: true,
// },
// ];
// for (const slider of sliders) {
// await SliderModel.create(slider);
// }
// logger.info(" Sliders Seeded");
const existingBanners = await BannerModel.countDocuments({});
if (existingBanners && existingBanners == 16) return;
await BannerModel.deleteMany({});
const banners = [
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر ۱",
title: "خوش آمدید به صفحه اصلی",
linkUrl: "/banner1",
isActive: true,
order: 1,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر ۲",
title: "درباره ما بیشتر بدانید",
linkUrl: "/banner2",
isActive: true,
order: 2,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر ۳",
title: "تماس با ما",
linkUrl: "/banner3",
isActive: true,
order: 3,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر ۴",
title: "خدمات ما را کشف کنید",
linkUrl: "/banner4",
isActive: true,
order: 4,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر ۵",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner5",
isActive: true,
order: 5,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 6",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner6",
isActive: true,
order: 6,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 7",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner7",
isActive: true,
order: 7,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 8",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner8",
isActive: true,
order: 8,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 9",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner9",
isActive: true,
order: 9,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 10",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner10",
isActive: true,
order: 10,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 11",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner11",
isActive: true,
order: 11,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 12",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner12",
isActive: true,
order: 12,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 13",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner13",
isActive: true,
order: 13,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 14",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner14",
isActive: true,
order: 14,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 15",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner15",
isActive: true,
order: 15,
},
{
imageUrl: "https://storage.shinan.ir/banner-placeholder.png",
altText: "بنر 16",
title: "محصولات ما را مشاهده کنید",
linkUrl: "/banner16",
isActive: true,
order: 16,
},
];
await BannerModel.insertMany(banners);
logger.info("Banners seeding completed!");
} catch (error) {
logger.error("Error seeding the Medias: ", error);
}
}
+50
View File
@@ -0,0 +1,50 @@
import { PaymentMethodType } from "../../common/enums/payment.enum";
import { Logger } from "../../core/logging/logger";
import { PaymentMethodModel } from "../../modules/payment/models/paymentMethod.model";
// Define payment method data
const paymentMethods = [
{
title_fa: "پرداخت اینترنتی",
title_en: "Internet Payment Gateway (IPG)",
description: "پرداخت آنلاین با تمامی کارت‌های بانکی",
provider: "Zarinpal",
isActive: true,
type: PaymentMethodType.Online,
},
{
title_fa: "پرداخت اینترنتی",
title_en: "Internet Payment Gateway (IPG)",
description: "پرداخت آنلاین با تمامی کارت‌های بانکی",
provider: "asanPardakht",
isActive: false,
type: PaymentMethodType.Online,
},
{
title_fa: "پرداخت در محل (با کارت بانکی)",
title_en: "POS",
description: "هنگام تحویل از طریق کارت‌های بانکی",
isActive: false,
type: PaymentMethodType.POS,
},
{
title_fa: "کیف پول",
title_en: "Wallet",
isActive: false,
type: PaymentMethodType.Wallet,
},
// Add more payment methods as necessary
];
// Seeder function to insert the payment methods
export const seedPaymentMethods = async (logger: Logger) => {
try {
logger.info("PaymentMethods seeding started");
await PaymentMethodModel.insertMany(paymentMethods);
logger.info("Payment methods seeded successfully");
} catch (error) {
logger.error("Error seeding payment methods:", error);
}
};
+27
View File
@@ -0,0 +1,27 @@
import { Logger } from "../../core/logging/logger";
import { IPricing, PricingTypeEnum } from "../../modules/pricing/models/Abstraction/IPricing";
import { PricingModel } from "../../modules/pricing/models/pricing.model";
export const SeedPricing = async (logger: Logger) => {
const pricing: IPricing[] = [
{ type: PricingTypeEnum.INSERT_FEE, price: 100_000 },
{ type: PricingTypeEnum.PHOTOGRAPHY_FEE, price: 150_000 },
{ type: PricingTypeEnum.UNBOXING_VIDEO_FEE, price: 200_000 },
{ type: PricingTypeEnum.EXPERT_REVIEWS_FEE, price: 200_000 },
];
try {
logger.info("Pricing seeding started");
const existPricing = await PricingModel.countDocuments({});
if (existPricing && existPricing == 4) return;
await PricingModel.deleteMany({});
await PricingModel.insertMany(pricing);
logger.info("Pricing seeded successfully");
} catch (error) {
logger.error("Failed to Pricing:", error);
}
};
+325
View File
@@ -0,0 +1,325 @@
import { faker } from "@faker-js/faker";
faker.locale = "fa";
import { ProductMarketStatus } from "../../common/enums/product.enum";
import { Logger } from "../../core/logging/logger";
import { BrandModel } from "../../modules/brand/models/brand.model";
import { AttributeValueModel } from "../../modules/category/models/attributeValue.model";
import { CategoryModel } from "../../modules/category/models/category.model";
import { CategoryAttributeModel } from "../../modules/category/models/CategoryAttribute.model";
import { ColorModel } from "../../modules/category/models/color.model";
import { MeterageModel } from "../../modules/category/models/meterage.model";
import { SizeModel } from "../../modules/category/models/size.model";
import { ISpecifications } from "../../modules/product/models/Abstraction/IProduct";
import { ProductModel } from "../../modules/product/models/product.model";
import { ProductVariantModel } from "../../modules/product/models/productVariant.model";
import { SellerModel } from "../../modules/seller/models/seller.model";
import { ShipmentModel } from "../../modules/shipment/models/shipment.model";
import { ShopModel } from "../../modules/shop/models/shop.model";
import { WalletModel } from "../../modules/wallet/models/wallet.model";
import { WarrantyModel } from "../../modules/warranty/models/warranty.model";
import { TimeService } from "../../utils/time.service";
import { CreateFakeSellerData, createFakeShopData, fakeProductsData } from "../data/product";
type ProductCategory =
| "mobile"
| "stationery"
| "electric-electrical"
| "tools-equipment"
| "audio-visual"
| "computer"
| "game-console"
| "sports-travel"
| "fashion"
| "home-appliances"
| "mobile-phones"
| "tablets"
| "pens"
| "paper-notebooks"
| "bulbs"
| "cables-wires"
| "wrenches-screwdrivers"
| "drills"
| "televisions"
| "speakers"
| "laptops"
| "mouse-keyboards"
| "playstations"
| "xbox"
| "sports-equipment"
| "cameras"
| "headphones"
| "travel-equipment"
| "women-clothing"
| "men-clothing"
| "kitchen-appliances"
| "smart-watch"
| "power-banks"
| "cleaning-appliances"
| "malicious";
type ProductBrand =
| "Samsung"
| "LG"
| "Bosch"
| "Apple"
| "Asus"
| "Xiaomi"
| "Sony"
| "JBL"
| "Bose"
| "Huawei"
| "Nokia"
| "Nikon"
| "Panasonic"
| "Anker"
| "Microsoft"
| "Lenovo"
| "Pilot"
| "Sheaffer"
| "Parker"
| "Lamy"
| "Parker"
| "Philips"
| "Optonique"
| "NoorKala"
| "Acer"
| "Zara"
| "H&M"
| "Gucci"
| "Dior"
| "Gucci"
| "Gucci"
| "malicious";
const productMapping = (productModel: string) => {
let category: ProductCategory;
let brand: ProductBrand;
switch (productModel) {
case "SAMSUNG123":
case "SAMGALTAB567":
brand = "Samsung";
category = productModel === "SAMSUNG123" ? "televisions" : "tablets";
break;
case "LGWASH456":
brand = "LG";
category = "kitchen-appliances";
break;
case "LGOLED789":
brand = "LG";
category = "televisions";
break;
case "BOSCHFRIDGE789":
brand = "Bosch";
category = "kitchen-appliances";
break;
case "IPHONE13PRO":
case "APPLEWATCH123":
brand = "Apple";
category = productModel === "IPHONE13PRO" ? "mobile-phones" : "smart-watch";
break;
case "ASUSLAP234":
brand = "Asus";
category = "laptops";
break;
case "MI11PRO":
brand = "Xiaomi";
category = "mobile-phones";
break;
case "SONYWH123":
case "SONYCAM456":
case "SONYSPK234":
brand = "Sony";
category = productModel === "SONYWH123" ? "headphones" : productModel === "SONYCAM456" ? "cameras" : "speakers";
break;
case "JBLSPK789":
brand = "JBL";
category = "speakers";
break;
case "NIKONCAM123":
brand = "Nikon";
category = "cameras";
break;
case "BOSEWH789":
brand = "Bose";
category = "headphones";
break;
case "HUAWEITAB1":
brand = "Huawei";
category = "tablets";
break;
case "NOKIAG20":
brand = "Nokia";
category = "mobile-phones";
break;
case "PANAMW234":
brand = "Panasonic";
category = "kitchen-appliances";
break;
case "ANKERPB100":
brand = "Anker";
category = "power-banks";
break;
case "PS5DISC":
brand = "Sony";
category = "playstations";
break;
default:
brand = "malicious";
category = "malicious";
}
return { brand, category };
};
const getBrandAndCategoryForProduct = async (product: (typeof fakeProductsData)[0]) => {
const { brand: brandName, category: categoryName } = productMapping(product.model) || {};
const category = await CategoryModel.findOne({ title_en: categoryName });
if (!category) {
throw new Error(`Category not found for product: ${product.title_fa}`);
}
const brand = await BrandModel.findOne({ title_en: brandName, category: category._id.toString() });
if (!brand) {
throw new Error(`Brand not found for product: ${product.title_fa}`);
}
return { brand, category };
};
const createFakeProductVariant = (
productId: number,
shopId: string,
warrantyId: number,
colorId?: number,
sizeId?: number,
meterageId?: number,
) => {
return new ProductVariantModel({
product: productId,
rate: faker.datatype.float({ min: 1, max: 5 }),
warranty: warrantyId,
shop: shopId,
color: colorId,
size: sizeId,
meterage: meterageId,
sellerSpecialCode: crypto.randomUUID().slice(0, 6).toUpperCase(),
market_status: faker.helpers.arrayElement([ProductMarketStatus.Marketable]),
postingTime: faker.datatype.number({ min: 1, max: 10 }),
price: {
order_limit: faker.datatype.number({ min: 1, max: 10 }),
retailPrice: faker.datatype.number({ min: 10000, max: 100000000 }),
is_specialSale: true,
discount_percent: faker.datatype.number({ min: 1, max: 50 }),
specialSale_order_limit: faker.datatype.number({ min: 1, max: 5 }),
specialSale_quantity: faker.datatype.number({ min: 1, max: 5 }),
specialSale_endDate: TimeService.convertGregorianToPersian(faker.date.future()),
},
saleFormat: {
retail: true,
wholeSale: [
{ from: 10, to: 30, price: faker.datatype.number({ min: 10000, max: 100000000 }) },
{ from: 30, to: 50, price: faker.datatype.number({ min: 10000, max: 100000000 }) },
{ from: 50, to: 100, price: faker.datatype.number({ min: 10000, max: 100000000 }) },
],
},
stock: faker.datatype.number({ min: 20, max: 100 }),
dimensions: {
package_weight: faker.datatype.number({ min: 1, max: 5 }),
package_height: faker.datatype.number({ min: 10, max: 100 }),
package_length: faker.datatype.number({ min: 10, max: 100 }),
package_width: faker.datatype.number({ min: 10, max: 100 }),
},
});
};
export const seedProduct = async (logger: Logger) => {
try {
logger.info("start seeding products");
// Fetch warranties and shipment methods
const warranties = await WarrantyModel.find().limit(10);
const shipments = (await ShipmentModel.find()).map((shipper) => shipper._id);
const colors = (await ColorModel.find()).map((color) => color._id);
const sizes = (await SizeModel.find()).map((size) => size._id);
const meterages = (await MeterageModel.find()).map((meterage) => meterage._id);
if (!warranties.length) {
throw new Error("No warranties found in the database. Please seed them first.");
}
const remainingProducts = [...fakeProductsData];
for (let i = 0; i < 10; i++) {
// Create fake seller
const seller = await SellerModel.create(CreateFakeSellerData());
await WalletModel.create({ seller: seller._id.toString() });
const shop = await ShopModel.create(createFakeShopData(faker.helpers.arrayElements(shipments, 3), seller._id.toString()));
const sellerProducts = remainingProducts.splice(0, 5);
for (const productData of sellerProducts) {
// Get the correct brand and category for the product
const { brand, category } = await getBrandAndCategoryForProduct(productData);
const catAttributes = await CategoryAttributeModel.find({ category: category._id.toString() });
const attributeValues = await AttributeValueModel.find({ attribute: { $in: catAttributes.map((att) => att._id) } });
const specifications: ISpecifications[] = catAttributes.map((catAttr) => {
const valuesForAttribute = attributeValues
.filter((attValue) => attValue.attribute.toString() === catAttr._id.toString())
.map((attValue) => attValue.text);
return {
title: catAttr.title,
values: valuesForAttribute,
};
});
const product = await new ProductModel({
...productData,
shop: shop._id,
specifications,
brand: brand._id.toString(),
category: category._id.toString(),
}).save();
for (let k = 0; k < 3; k++) {
const variant = await createFakeProductVariant(
product._id,
shop._id.toString(),
faker.helpers.arrayElement(warranties)._id,
productData.color ? faker.helpers.arrayElement(colors) : undefined,
productData.size ? faker.helpers.arrayElement(sizes) : undefined,
productData.meterage ? faker.helpers.arrayElement(meterages) : undefined,
).save();
product.variants.push(variant._id);
await product.save();
}
}
if (remainingProducts.length < 5) break;
}
logger.info("Seeding product completed!");
} catch (error) {
console.error(error);
logger.error("Failed to seed product and variant:", error);
}
};
+61
View File
@@ -0,0 +1,61 @@
import { Logger } from "../../core/logging/logger";
import { ReportQuestionModel } from "../../modules/product/models/reportQuestion.model";
const Questions = [
{
title: "نام کالا نادرست است",
type: "checkbox",
},
{
title: "عکس کالا نامناسب است",
type: "checkbox",
},
{
title: "مشخصات کالا نادرست است",
type: "checkbox",
},
{
title: "توضیحات کالا نادرست است",
type: "checkbox",
},
{
title: "کالا غیراصل است",
type: "checkbox",
},
{
title: "کالا ناقض قوانین جمهوری اسلامی است",
type: "checkbox",
},
{
title: "کالا تکراری است",
type: "checkbox",
// related_questions: [relatedQues._id],
},
];
export const ReportQuesSeeder = async (logger: Logger) => {
try {
logger.info("ReportQuestion seeding started");
await ReportQuestionModel.deleteMany();
for (const question of Questions) {
await ReportQuestionModel.create(question);
}
// const relatedQues = await ReportQuestionModel.create({
// title: "کد کالای مشابه ",
// type: "number",
// placeholder: "https://shinan.ir/product/SHP-313420/",
// });
// await ReportQuestionModel.create({
// title: "کالا تکراری است",
// type: "checkbox",
// related_questions: [relatedQues._id],
// });
logger.info("report questions seeded successfully");
} catch (error) {
logger.error("error seeding the report questions:", error);
}
};
+36
View File
@@ -0,0 +1,36 @@
import { Logger } from "../../core/logging/logger";
import { RoleEnum } from "../../modules/admin/models/Abstraction/IRole";
import { RoleModel } from "../../modules/admin/models/role.model";
const createDefaultRoles = async (logger: Logger) => {
logger.info("create roles started", "SEED");
// const roles = Object.values(RoleEnum);
const rolesWithPermissions = [
{
role: RoleEnum.SUPERADMIN,
},
{
role: RoleEnum.MODERATOR,
},
{
role: RoleEnum.EDITOR,
},
];
const createdRoles = await Promise.all(
rolesWithPermissions.map(async ({ role }) => {
const existingRole = await RoleModel.findOne({ name: role });
if (!existingRole) {
return RoleModel.create({ name: role });
}
return existingRole;
}),
);
if (createdRoles) {
logger.info("Default roles created", "SEED");
} else {
logger.warn("Default roles already exists", "SEED");
}
};
export { createDefaultRoles };
+75
View File
@@ -0,0 +1,75 @@
import { DeliveryType } from "../../common/enums/shipment.enum";
import { Logger } from "../../core/logging/logger";
import { ShipmentModel } from "../../modules/shipment/models/shipment.model";
export const SeedShipment = async (logger: Logger) => {
const providers = [
{
name: "پست",
description: "ارسال توسط پست",
costs: [
{ weightRange: { min: 0, max: 1 }, cost_first: 40000, cost_rest: 2000 },
{ weightRange: { min: 1, max: 5 }, cost_first: 80000, cost_rest: 2000 },
{ weightRange: { min: 5, max: 10 }, cost_first: 100000, cost_rest: 2000 },
],
deliveryTime: 5, // Standard (3-5 days)
deliveryType: DeliveryType.Standard,
},
{
name: "چاپار",
description: "ارائه بهترین راه حل های جهانی لجستیک چاپار",
costs: [
{ weightRange: { min: 0, max: 2 }, cost_first: 40000, cost_rest: 2000 },
{ weightRange: { min: 2, max: 6 }, cost_first: 80000, cost_rest: 2000 },
{ weightRange: { min: 6, max: 12 }, cost_first: 100000, cost_rest: 2000 },
],
deliveryTime: 6, // Standard (4-6 days)
deliveryType: DeliveryType.Standard,
},
{
name: "پیک",
description: "ارسال توسط پیک",
costs: [
{ weightRange: { min: 0, max: 1 }, cost_first: 40000, cost_rest: 2000 },
{ weightRange: { min: 1, max: 3 }, cost_first: 80000, cost_rest: 2000 },
{ weightRange: { min: 3, max: 6 }, cost_first: 100000, cost_rest: 2000 },
],
deliveryTime: 0, // Same Day
deliveryType: DeliveryType.SameDay,
},
{
name: "تیپاکس",
description: "ارسال بسته های پستی در سریعترین زمان، از درب منزل با امکان پرداخت هزینه بعد از ارسال و پوشش تمام نقاط ایران",
costs: [
{ weightRange: { min: 0, max: 1 }, cost_first: 40000, cost_rest: 2000 },
{ weightRange: { min: 1, max: 5 }, cost_first: 80000, cost_rest: 2000 },
{ weightRange: { min: 5, max: 10 }, cost_first: 100000, cost_rest: 2000 },
],
deliveryTime: 2, // Express (1-2 days)
deliveryType: DeliveryType.Express,
},
{
name: "باربری",
description: "ارسال توسط باربری",
costs: [
{ weightRange: { min: 0, max: 10 }, cost_first: 40000, cost_rest: 2000 },
{ weightRange: { min: 10, max: 20 }, cost_first: 80000, cost_rest: 2000 },
{ weightRange: { min: 20, max: 50 }, cost_first: 100000, cost_rest: 2000 },
],
deliveryTime: 7, // Freight (5-7 days)
deliveryType: DeliveryType.Standard,
},
];
try {
logger.info("ShipmentMethod seeding started");
for (const provider of providers) {
await ShipmentModel.create(provider);
}
logger.info("Shipment Providers seeded successfully");
} catch (error) {
logger.error("Error seeding Shipment providers:", error);
}
};
+38
View File
@@ -0,0 +1,38 @@
import { Logger } from "../../core/logging/logger";
import { TicketCategoryModel } from "../../modules/ticket/models/ticketCategory.model";
// Define ticket categories to seed
const ticketCategories = [
{
title_fa: "مشکل فنی",
description: "مشکلات مربوط به سیستم، سایت یا فروشگاه.",
},
{
title_fa: "مشکلات مالی",
description: "مشکلات مربوط به پرداخت‌ها و مسائل مالی.",
},
{
title_fa: "پشتیبانی محصول",
description: "سوالات و پشتیبانی‌های مربوط به محصولات.",
},
{
title_fa: "مشکلات ارسال",
description: "مشکلات مربوط به ارسال سفارشات و حمل و نقل.",
},
{
title_fa: "درخواست راهنمایی",
description: "درخواست‌ها برای راهنمایی و کمک در مورد مسائل مختلف.",
},
];
export const seedTicketCategories = async (logger: Logger) => {
try {
logger.info("start seeding the ticket category");
await TicketCategoryModel.insertMany(ticketCategories);
logger.info("Ticket categories seeded successfully!");
} catch (error) {
logger.error("Failed to seed ticket categories:", error);
}
};
+47
View File
@@ -0,0 +1,47 @@
import { faker } from "@faker-js/faker"; // Use faker for generating random data
import { StatusEnum } from "../../common/enums/status.enum";
import { Logger } from "../../core/logging/logger";
import { WarrantyModel } from "../../modules/warranty/models/warranty.model";
const warrantyNames = [
"Iran Warranty Co.",
"Pars Guarantee",
"Tehran Warranty Services",
"Safir Warranty",
"Farda Warranty Solutions",
"Aryan Protection",
"Mehr Warranty",
"Saman Warranty Group",
"Persian Warranty Solutions",
"Shahab After Sales",
"Payam Warranty",
"Kavir Protection",
"Tajrish Warranty",
"Sina Warranty",
"Atlas Warranty Services",
"Sepahan Warranty",
"Kish Warranty Group",
"Navid Warranty Solutions",
"Alborz Protection Services",
"Raha Warranty Solutions",
];
export const seedWarranty = async (logger: Logger) => {
try {
logger.info("Warranty seeding started");
for (const name of warrantyNames) {
await WarrantyModel.create({
name,
status: StatusEnum.Approved,
duration: faker.datatype.number({ min: 1, max: 36 }) + " months",
logoUrl: faker.image.business(),
});
}
logger.info("Warranty seeding complete!");
} catch (error) {
logger.error("Error seeding warranties:", error);
}
};