Add demo data seed script
This commit is contained in:
@@ -10,7 +10,8 @@
|
|||||||
"prisma:generate": "prisma generate",
|
"prisma:generate": "prisma generate",
|
||||||
"prisma:migrate": "prisma migrate deploy",
|
"prisma:migrate": "prisma migrate deploy",
|
||||||
"prisma:push": "prisma db push",
|
"prisma:push": "prisma db push",
|
||||||
"seed": "node scripts/seed.js"
|
"seed": "node scripts/seed.js",
|
||||||
|
"seed:demo": "node scripts/seed-demo.js"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
|
|||||||
534
scripts/seed-demo.js
Normal file
534
scripts/seed-demo.js
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
import 'dotenv/config';
|
||||||
|
|
||||||
|
import { prisma } from '../src/prisma-client.js';
|
||||||
|
|
||||||
|
const MANAGER_EMAIL = 'manager@fregat.local';
|
||||||
|
const DEMO_EMAIL_DOMAIN = 'demo.fregat.local';
|
||||||
|
const DEMO_ORDER_PREFIX = 'DBG-';
|
||||||
|
const DEMO_CLIENT_COUNT = Number.parseInt(process.env.DEMO_CLIENTS ?? '20', 10);
|
||||||
|
const DEMO_ORDER_COUNT = Number.parseInt(process.env.DEMO_ORDERS ?? '40', 10);
|
||||||
|
|
||||||
|
const FIRST_NAMES = [
|
||||||
|
'Алексей', 'Мария', 'Ирина', 'Дмитрий', 'Светлана',
|
||||||
|
'Павел', 'Ольга', 'Иван', 'Наталья', 'Егор',
|
||||||
|
'Виктория', 'Максим', 'Елена', 'Роман', 'Анна',
|
||||||
|
'Кирилл', 'Юлия', 'Андрей', 'Татьяна', 'Сергей',
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAST_NAMES = [
|
||||||
|
'Иванов', 'Петрова', 'Смирнова', 'Козлов', 'Васильева',
|
||||||
|
'Федоров', 'Морозова', 'Захаров', 'Орлова', 'Новиков',
|
||||||
|
'Романова', 'Соколов', 'Беляева', 'Громов', 'Крылова',
|
||||||
|
'Титов', 'Борисова', 'Попов', 'Лебедева', 'Макаров',
|
||||||
|
];
|
||||||
|
|
||||||
|
const CITIES = [
|
||||||
|
'Москва',
|
||||||
|
'Санкт-Петербург',
|
||||||
|
'Казань',
|
||||||
|
'Екатеринбург',
|
||||||
|
'Новосибирск',
|
||||||
|
'Нижний Новгород',
|
||||||
|
'Самара',
|
||||||
|
'Краснодар',
|
||||||
|
'Ростов-на-Дону',
|
||||||
|
'Воронеж',
|
||||||
|
];
|
||||||
|
|
||||||
|
const STREETS = [
|
||||||
|
'Ленинградский проспект',
|
||||||
|
'Кубинская улица',
|
||||||
|
'улица Родины',
|
||||||
|
'Промышленная улица',
|
||||||
|
'улица Победы',
|
||||||
|
'Складской проезд',
|
||||||
|
'Транспортная улица',
|
||||||
|
'улица Энергетиков',
|
||||||
|
'Рабочая улица',
|
||||||
|
'Индустриальный проспект',
|
||||||
|
];
|
||||||
|
|
||||||
|
const COMPANY_PREFIXES = [
|
||||||
|
'ТД', 'ПК', 'Логистик', 'Сервис', 'Группа',
|
||||||
|
'Снаб', 'Пром', 'Регион', 'Партнер', 'Трейд',
|
||||||
|
];
|
||||||
|
|
||||||
|
const COMPANY_SUFFIXES = [
|
||||||
|
'Пласт', 'Пак', 'Транс', 'Маркет', 'Снабжение',
|
||||||
|
'Лайн', 'Система', 'Поставка', 'Ритейл', 'Ресурс',
|
||||||
|
];
|
||||||
|
|
||||||
|
const ORDER_STATUS_CYCLE = [
|
||||||
|
'NEW',
|
||||||
|
'MANAGER_PROCESSING',
|
||||||
|
'WAITING_DOUBLE_CONFIRM',
|
||||||
|
'CONFIRMED',
|
||||||
|
'IN_PROGRESS',
|
||||||
|
'COMPLETED',
|
||||||
|
];
|
||||||
|
|
||||||
|
function formatIndex(index) {
|
||||||
|
return String(index).padStart(2, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildClientEmail(index) {
|
||||||
|
return `client${formatIndex(index)}@${DEMO_EMAIL_DOMAIN}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildInn(index) {
|
||||||
|
return `7702${String(index).padStart(6, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildOgrn(index) {
|
||||||
|
return `102770${String(index).padStart(7, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildBik(index) {
|
||||||
|
return `0445${String(10000 + index).slice(-5)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAccount(prefix, index) {
|
||||||
|
return `${prefix}${String(100000000000000000 + index).slice(-18)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function atMiddayDaysAgo(daysAgo) {
|
||||||
|
const date = new Date();
|
||||||
|
date.setHours(12, 0, 0, 0);
|
||||||
|
date.setDate(date.getDate() - daysAgo);
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addHours(date, hours) {
|
||||||
|
return new Date(date.getTime() + (hours * 60 * 60 * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toMoney(value) {
|
||||||
|
return value.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createOrderTimeline(status, createdAt) {
|
||||||
|
const steps = [
|
||||||
|
{ status: 'NEW', note: '[demo] Заказ создан клиентом.' },
|
||||||
|
{ status: 'MANAGER_PROCESSING', note: '[demo] Менеджер взял заказ в работу.' },
|
||||||
|
{ status: 'WAITING_DOUBLE_CONFIRM', note: '[demo] Согласование условий и цены.' },
|
||||||
|
{ status: 'CONFIRMED', note: '[demo] Стороны подтвердили заказ.' },
|
||||||
|
{ status: 'IN_PROGRESS', note: '[demo] Заказ передан в исполнение.' },
|
||||||
|
{ status: 'COMPLETED', note: '[demo] Заказ доставлен клиенту.' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const targetIndex = steps.findIndex((step) => step.status === status);
|
||||||
|
if (targetIndex === -1) {
|
||||||
|
return [steps[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return steps.slice(0, targetIndex + 1).map((step, index) => ({
|
||||||
|
...step,
|
||||||
|
createdAt: addHours(createdAt, index * 6),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function orderKindForIndex(index) {
|
||||||
|
return index % 5 === 0 ? 'CALCULATION' : 'READY';
|
||||||
|
}
|
||||||
|
|
||||||
|
function orderStatusForIndex(index) {
|
||||||
|
return ORDER_STATUS_CYCLE[index % ORDER_STATUS_CYCLE.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
function companyNameForIndex(index) {
|
||||||
|
const prefix = COMPANY_PREFIXES[index % COMPANY_PREFIXES.length];
|
||||||
|
const suffix = COMPANY_SUFFIXES[index % COMPANY_SUFFIXES.length];
|
||||||
|
return `${prefix} ${suffix} ${formatIndex(index)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fullNameForIndex(index) {
|
||||||
|
return `${FIRST_NAMES[(index - 1) % FIRST_NAMES.length]} ${LAST_NAMES[(index - 1) % LAST_NAMES.length]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upsertClient(index) {
|
||||||
|
const companyName = companyNameForIndex(index);
|
||||||
|
const company = await prisma.company.upsert({
|
||||||
|
where: { inn: buildInn(index) },
|
||||||
|
update: { name: companyName },
|
||||||
|
create: {
|
||||||
|
name: companyName,
|
||||||
|
inn: buildInn(index),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = await prisma.user.upsert({
|
||||||
|
where: { email: buildClientEmail(index) },
|
||||||
|
update: {
|
||||||
|
fullName: fullNameForIndex(index),
|
||||||
|
role: 'CLIENT',
|
||||||
|
companyId: company.id,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
email: buildClientEmail(index),
|
||||||
|
fullName: fullNameForIndex(index),
|
||||||
|
role: 'CLIENT',
|
||||||
|
companyId: company.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.counterpartyProfile.upsert({
|
||||||
|
where: { userId: user.id },
|
||||||
|
update: {
|
||||||
|
companyName,
|
||||||
|
companyFullName: `${companyName}, общество с ограниченной ответственностью`,
|
||||||
|
inn: buildInn(index),
|
||||||
|
kpp: `7702${String(2000 + index).slice(-4)}`,
|
||||||
|
ogrn: buildOgrn(index),
|
||||||
|
legalAddress: `${CITIES[(index - 1) % CITIES.length]}, ${STREETS[(index - 1) % STREETS.length]}, ${10 + index}`,
|
||||||
|
bankName: 'АО Тест Банк',
|
||||||
|
bik: buildBik(index),
|
||||||
|
correspondentAccount: buildAccount('30101', index),
|
||||||
|
checkingAccount: buildAccount('40702', index),
|
||||||
|
signerFullName: fullNameForIndex(index),
|
||||||
|
signerPosition: 'Генеральный директор',
|
||||||
|
signerBasis: 'Устав',
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
userId: user.id,
|
||||||
|
companyName,
|
||||||
|
companyFullName: `${companyName}, общество с ограниченной ответственностью`,
|
||||||
|
inn: buildInn(index),
|
||||||
|
kpp: `7702${String(2000 + index).slice(-4)}`,
|
||||||
|
ogrn: buildOgrn(index),
|
||||||
|
legalAddress: `${CITIES[(index - 1) % CITIES.length]}, ${STREETS[(index - 1) % STREETS.length]}, ${10 + index}`,
|
||||||
|
bankName: 'АО Тест Банк',
|
||||||
|
bik: buildBik(index),
|
||||||
|
correspondentAccount: buildAccount('30101', index),
|
||||||
|
checkingAccount: buildAccount('40702', index),
|
||||||
|
signerFullName: fullNameForIndex(index),
|
||||||
|
signerPosition: 'Генеральный директор',
|
||||||
|
signerBasis: 'Устав',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const addressLabel = 'Основной адрес';
|
||||||
|
const addressValue = `${CITIES[(index - 1) % CITIES.length]}, ${STREETS[(index - 1) % STREETS.length]}, ${20 + index}`;
|
||||||
|
const existingAddress = await prisma.deliveryAddress.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: user.id,
|
||||||
|
label: addressLabel,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const address = existingAddress
|
||||||
|
? await prisma.deliveryAddress.update({
|
||||||
|
where: { id: existingAddress.id },
|
||||||
|
data: {
|
||||||
|
address: addressValue,
|
||||||
|
unrestrictedValue: addressValue,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: await prisma.deliveryAddress.create({
|
||||||
|
data: {
|
||||||
|
userId: user.id,
|
||||||
|
label: addressLabel,
|
||||||
|
address: addressValue,
|
||||||
|
unrestrictedValue: addressValue,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.user.update({
|
||||||
|
where: { id: user.id },
|
||||||
|
data: {
|
||||||
|
defaultDeliveryAddressId: address.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { user, address };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function rebuildMessengerConnections(clients) {
|
||||||
|
await prisma.messengerConnection.deleteMany({
|
||||||
|
where: {
|
||||||
|
userId: {
|
||||||
|
in: clients.map((entry) => entry.user.id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [index, client] of clients.entries()) {
|
||||||
|
const demoIndex = index + 1;
|
||||||
|
|
||||||
|
if (demoIndex % 2 === 1) {
|
||||||
|
await prisma.messengerConnection.create({
|
||||||
|
data: {
|
||||||
|
userId: client.user.id,
|
||||||
|
type: 'TELEGRAM',
|
||||||
|
channelId: `70000${demoIndex}`,
|
||||||
|
displayName: client.user.fullName,
|
||||||
|
username: `fregat_demo_${formatIndex(demoIndex)}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (demoIndex % 3 === 0) {
|
||||||
|
await prisma.messengerConnection.create({
|
||||||
|
data: {
|
||||||
|
userId: client.user.id,
|
||||||
|
type: 'MAX',
|
||||||
|
channelId: `90000${demoIndex}`,
|
||||||
|
displayName: client.user.fullName,
|
||||||
|
username: `max_demo_${formatIndex(demoIndex)}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cleanupDemoData(demoUserIds) {
|
||||||
|
const demoOrders = await prisma.order.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ code: { startsWith: DEMO_ORDER_PREFIX } },
|
||||||
|
{ customerId: { in: demoUserIds } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
const demoOrderIds = demoOrders.map((order) => order.id);
|
||||||
|
|
||||||
|
if (demoOrderIds.length) {
|
||||||
|
await prisma.orderStatusEvent.deleteMany({
|
||||||
|
where: { orderId: { in: demoOrderIds } },
|
||||||
|
});
|
||||||
|
await prisma.orderItem.deleteMany({
|
||||||
|
where: { orderId: { in: demoOrderIds } },
|
||||||
|
});
|
||||||
|
await prisma.bonusTransaction.deleteMany({
|
||||||
|
where: { orderId: { in: demoOrderIds } },
|
||||||
|
});
|
||||||
|
await prisma.order.deleteMany({
|
||||||
|
where: { id: { in: demoOrderIds } },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.rewardWithdrawalRequest.deleteMany({
|
||||||
|
where: { requesterId: { in: demoUserIds } },
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.bonusTransaction.deleteMany({
|
||||||
|
where: {
|
||||||
|
userId: { in: demoUserIds },
|
||||||
|
reason: { startsWith: '[demo]' },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.referralLink.deleteMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ referrerId: { in: demoUserIds } },
|
||||||
|
{ refereeId: { in: demoUserIds } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createReferralLinks(managerId, clients) {
|
||||||
|
const links = [];
|
||||||
|
|
||||||
|
for (let index = 0; index < Math.min(10, Math.floor(clients.length / 2)); index += 1) {
|
||||||
|
const referrer = clients[index].user;
|
||||||
|
const referee = clients[index + 10]?.user;
|
||||||
|
if (!referee) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = await prisma.referralLink.create({
|
||||||
|
data: {
|
||||||
|
referrerId: referrer.id,
|
||||||
|
refereeId: referee.id,
|
||||||
|
createdById: managerId,
|
||||||
|
bonusPercent: toMoney(5 + (index % 4) * 2.5),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
links.push(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createOrders(managerId, clients, products, referralLinks) {
|
||||||
|
const referralByRefereeId = new Map(referralLinks.map((link) => [link.refereeId, link]));
|
||||||
|
let completedOrders = 0;
|
||||||
|
|
||||||
|
for (let index = 1; index <= DEMO_ORDER_COUNT; index += 1) {
|
||||||
|
const client = clients[(index - 1) % clients.length];
|
||||||
|
const createdAt = atMiddayDaysAgo(DEMO_ORDER_COUNT - index + 1);
|
||||||
|
const status = orderStatusForIndex(index - 1);
|
||||||
|
const kind = orderKindForIndex(index);
|
||||||
|
const itemCount = 1 + (index % 3);
|
||||||
|
const orderProducts = Array.from({ length: itemCount }, (_, itemIndex) => (
|
||||||
|
products[(index + itemIndex * 3) % products.length]
|
||||||
|
));
|
||||||
|
|
||||||
|
const preparedItems = orderProducts.map((product, itemIndex) => {
|
||||||
|
const quantity = 5 + ((index + itemIndex * 2) % 18);
|
||||||
|
const unitPrice = 72 + ((index * 11 + itemIndex * 7) % 65);
|
||||||
|
return {
|
||||||
|
product,
|
||||||
|
quantity,
|
||||||
|
unitPrice,
|
||||||
|
lineTotal: quantity * unitPrice,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalPrice = preparedItems.reduce((sum, item) => sum + item.lineTotal, 0);
|
||||||
|
const deliveryFee = 1200 + (index % 5) * 350;
|
||||||
|
|
||||||
|
const order = await prisma.order.create({
|
||||||
|
data: {
|
||||||
|
code: `${DEMO_ORDER_PREFIX}${String(3000 + index)}`,
|
||||||
|
kind,
|
||||||
|
customerId: client.user.id,
|
||||||
|
managerId,
|
||||||
|
deliveryAddressId: client.address.id,
|
||||||
|
deliveryAddress: client.address.address,
|
||||||
|
deliveryTerms: index % 4 === 0
|
||||||
|
? 'Доставка до адреса клиента'
|
||||||
|
: 'Самовывоз со склада после подтверждения',
|
||||||
|
deliveryFee: toMoney(deliveryFee),
|
||||||
|
totalPrice: toMoney(totalPrice + deliveryFee),
|
||||||
|
status,
|
||||||
|
clientApproved: ['CONFIRMED', 'IN_PROGRESS', 'COMPLETED'].includes(status) ? true : null,
|
||||||
|
managerApproved: ['WAITING_DOUBLE_CONFIRM', 'CONFIRMED', 'IN_PROGRESS', 'COMPLETED'].includes(status) ? true : null,
|
||||||
|
calculationPayload: kind === 'CALCULATION'
|
||||||
|
? {
|
||||||
|
note: 'Демо-расчет для интерфейсов менеджера.',
|
||||||
|
requestedAt: createdAt.toISOString(),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
createdAt,
|
||||||
|
updatedAt: addHours(createdAt, 12),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const item of preparedItems) {
|
||||||
|
await prisma.orderItem.create({
|
||||||
|
data: {
|
||||||
|
orderId: order.id,
|
||||||
|
productId: item.product.id,
|
||||||
|
productName: item.product.name,
|
||||||
|
quantity: item.quantity.toFixed(3),
|
||||||
|
unitPrice: toMoney(item.unitPrice),
|
||||||
|
createdAt,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeline = createOrderTimeline(status, createdAt);
|
||||||
|
for (const event of timeline) {
|
||||||
|
await prisma.orderStatusEvent.create({
|
||||||
|
data: {
|
||||||
|
orderId: order.id,
|
||||||
|
status: event.status,
|
||||||
|
actorUserId: managerId,
|
||||||
|
note: event.note,
|
||||||
|
createdAt: event.createdAt,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'COMPLETED') {
|
||||||
|
completedOrders += 1;
|
||||||
|
const referralLink = referralByRefereeId.get(client.user.id);
|
||||||
|
if (referralLink) {
|
||||||
|
const bonusAmount = Number((Number(totalPrice + deliveryFee) * Number(referralLink.bonusPercent) / 100).toFixed(2));
|
||||||
|
await prisma.bonusTransaction.create({
|
||||||
|
data: {
|
||||||
|
userId: referralLink.referrerId,
|
||||||
|
amount: toMoney(bonusAmount),
|
||||||
|
reason: `[demo] Бонус за заказ ${order.code}`,
|
||||||
|
orderId: order.id,
|
||||||
|
referralLinkId: referralLink.id,
|
||||||
|
createdAt: addHours(createdAt, 18),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return completedOrders;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createWithdrawalDrafts(clients) {
|
||||||
|
const candidates = clients.slice(0, 3);
|
||||||
|
|
||||||
|
for (const [index, client] of candidates.entries()) {
|
||||||
|
await prisma.rewardWithdrawalRequest.create({
|
||||||
|
data: {
|
||||||
|
requesterId: client.user.id,
|
||||||
|
amount: toMoney(1500 + index * 750),
|
||||||
|
status: 'PENDING',
|
||||||
|
reviewComment: '[demo] Тестовая заявка на вывод.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
if (!Number.isFinite(DEMO_CLIENT_COUNT) || DEMO_CLIENT_COUNT < 2) {
|
||||||
|
throw new Error('DEMO_CLIENTS must be at least 2.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Number.isFinite(DEMO_ORDER_COUNT) || DEMO_ORDER_COUNT < 1) {
|
||||||
|
throw new Error('DEMO_ORDERS must be at least 1.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const manager = await prisma.user.findUnique({
|
||||||
|
where: { email: MANAGER_EMAIL },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!manager) {
|
||||||
|
throw new Error(`Manager ${MANAGER_EMAIL} not found. Run npm run seed first.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const products = await prisma.product.findMany({
|
||||||
|
where: { isActive: true },
|
||||||
|
orderBy: { sku: 'asc' },
|
||||||
|
take: 24,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (products.length < 6) {
|
||||||
|
throw new Error('Not enough active products. Run npm run seed first.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const clients = [];
|
||||||
|
for (let index = 1; index <= DEMO_CLIENT_COUNT; index += 1) {
|
||||||
|
clients.push(await upsertClient(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
const demoUserIds = clients.map((entry) => entry.user.id);
|
||||||
|
await cleanupDemoData(demoUserIds);
|
||||||
|
await rebuildMessengerConnections(clients);
|
||||||
|
|
||||||
|
const referralLinks = await createReferralLinks(manager.id, clients);
|
||||||
|
const completedOrders = await createOrders(manager.id, clients, products, referralLinks);
|
||||||
|
await createWithdrawalDrafts(clients);
|
||||||
|
|
||||||
|
const [usersCount, ordersCount] = await Promise.all([
|
||||||
|
prisma.user.count({
|
||||||
|
where: {
|
||||||
|
email: { endsWith: `@${DEMO_EMAIL_DOMAIN}` },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
prisma.order.count({
|
||||||
|
where: {
|
||||||
|
code: { startsWith: DEMO_ORDER_PREFIX },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
console.log(`Demo seed complete: ${usersCount} demo clients, ${ordersCount} demo orders, ${referralLinks.length} referral links, ${completedOrders} completed orders.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await main()
|
||||||
|
.finally(async () => {
|
||||||
|
await prisma.$disconnect();
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user