Files
tehran_tala/apps/api/prisma/insert-mock-products.js
T
s.esmaeiliandClaude Haiku 5.5 532ceee189 feat: move brand name to one config and redesign the accounting card
اپ: نام برند در همه‌ی صفحه‌ها و پیام‌ها یکسان شده و از یک تنظیم مرکزی خوانده می‌شود.
اپ: کارت حسابداری در صفحه‌ی مشتری بازطراحی شد؛ مانده‌ها و وضعیت لینک واضح‌تر نمایش داده می‌شوند.
پنل: کارت حسابداری در پرونده‌ی مشتری بازطراحی شد؛ مانده‌ها، آخرین ارسال و فرم لینک دستی واضح‌تر شده‌اند.
پنل: ستون «کد» در جدول‌ها به‌طور پیش‌فرض پنهان است و از انتخاب ستون‌ها قابل نمایش است.
پنل: تغییر نمایش ستون‌ها در جدول‌ها بلافاصله اعمال می‌شود.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-14 13:31:20 +03:30

119 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs = require('fs');
const path = require('path');
const seedPath = path.join(__dirname, 'seed.ts');
let content = fs.readFileSync(seedPath, 'utf-8');
const marker = ' imageCount += 1;\n }\n\n // \u2500\u2500 Featured collection';
if (!content.includes(marker)) {
console.error('MARKER NOT FOUND');
process.exit(1);
}
const insertion = ` imageCount += 1;
}
// \u2500\u2500 200 mock products for a realistic-looking catalogue \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
// These are generated, not hand-authored like the 5 above (whose ids are
// referenced elsewhere in this seed, e.g. by orders \u2014 left untouched).
// Images: real product photography does not exist in this project, so each
// mock product cycles through 6 generated SVG placeholders per category
// (apps/user-app/public/img/products/<slug>-N.svg), giving the catalogue
// grid genuine visual variety instead of one repeated icon.
const MOCK_CATEGORIES = [
{ slug: 'rings', id: ringsCategory.id, nouns: ['انگشتر نگین‌دار', 'انگشتر سولیتر', 'انگشتر آویزدار', 'انگشتر پهن', 'انگشتر ظریف', 'انگشتر رینگی'] },
{ slug: 'bracelets', id: braceletsCategory.id, nouns: ['دستبند زنجیری', 'دستبند پاندول', 'دستبند بافت', 'دستبند تنیس', 'دستبند پلاک‌دار', 'دستبند چرمی طلاکوب'] },
{ slug: 'necklaces', id: necklacesCategory.id, nouns: ['گردنبند آویز قلب', 'گردنبند ماه و ستاره', 'گردنبند ظریف', 'گردنبند رولو', 'گردنبند صلیب', 'گردنبند اسم'] },
{ slug: 'earrings', id: earringsCategory.id, nouns: ['گوشواره حلقه‌ای', 'گوشواره آویز', 'گوشواره میخی', 'گوشواره پروانه‌ای', 'گوشواره مرواریدی', 'گوشواره هندسی'] },
{ slug: 'coins', id: coinsCategory.id, nouns: ['ربع سکه بهار آزادی', 'نیم سکه بهار آزادی', 'سکه امامی', 'سکه پارسیان', 'شمش طلای ۱۰ گرمی', 'شمش طلای ۵ گرمی'] },
];
const MOCK_ADJECTIVES = ['کلاسیک', 'مدرن', 'مینیمال', 'لوکس', 'دست‌ساز', 'ظریف', 'خاص', 'شیک', 'سنتی', 'رزگلد'];
const MOCK_BRANDS = [brandMain.id, brandArtisan.id];
const MOCK_PRODUCT_COUNT = 200;
let mockImageCount = 0;
for (let i = 0; i < MOCK_PRODUCT_COUNT; i++) {
const cat = MOCK_CATEGORIES[i % MOCK_CATEGORIES.length];
const noun = cat.nouns[i % cat.nouns.length];
const adjective = MOCK_ADJECTIVES[i % MOCK_ADJECTIVES.length];
const brandId = MOCK_BRANDS[i % MOCK_BRANDS.length];
const productId = \`mock-product-\${i + 1}\`;
const title = \`\${noun} \${adjective} \${i + 1}\`;
// Deterministic but varied numeric fields \u2014 no randomness, so a re-seed
// is stable and diffable.
const baseWeight = 1.5 + ((i * 37) % 250) / 20; // ~1.5g .. ~14g
const wagePercent = (6 + ((i * 13) % 12)).toFixed(1); // 6.0% .. 17.9%
const qty = (i * 7) % 15; // 0..14, so some are genuinely out of stock
const isPreOrder = i % 9 === 0;
const product = await prisma.product.upsert({
where: { id: productId },
update: {},
create: {
id: productId,
title,
description: \`\${noun} با طراحی \${adjective}، مناسب استفاده روزمره یا هدیه.\`,
categoryId: cat.id,
brandId,
productCode: \`P-\${String(i + 1).padStart(4, '0')}\`,
},
});
const variantId = \`\${productId}-variant-1\`;
await prisma.productVariant.upsert({
where: { id: variantId },
update: {},
create: {
id: variantId,
productId: product.id,
title: 'استاندارد',
sku: \`MOCK-\${String(i + 1).padStart(4, '0')}\`,
rashWeightGrams: baseWeight.toFixed(3),
defaultWagePercent: wagePercent,
qty,
isPreOrder,
},
});
// A second variant on ~1 in 4 products, so the "\u062a\u0646\u0648\u0639 \u0648\u0632\u0646\u06cc" chip row has
// something real to show on more than the 5 hand-authored products.
if (i % 4 === 0) {
const variant2Id = \`\${productId}-variant-2\`;
await prisma.productVariant.upsert({
where: { id: variant2Id },
update: {},
create: {
id: variant2Id,
productId: product.id,
title: 'سایز بزرگ',
sku: \`MOCK-\${String(i + 1).padStart(4, '0')}-L\`,
rashWeightGrams: (baseWeight * 1.35).toFixed(3),
defaultWagePercent: wagePercent,
qty: (qty + 3) % 15,
isPreOrder,
},
});
}
const imgIndex = i % 6;
const imageUrl = \`/img/products/\${cat.slug}-\${imgIndex}.svg\`;
await prisma.productImage.upsert({
where: { id: \`\${productId}-img-1\` },
update: { url: imageUrl },
create: {
id: \`\${productId}-img-1\`,
productId: product.id,
url: imageUrl,
sortOrder: 0,
},
});
mockImageCount += 1;
}
imageCount += mockImageCount;
// \u2500\u2500 Featured collection`;
content = content.replace(marker, insertion);
fs.writeFileSync(seedPath, content, 'utf-8');
console.log('inserted mock product generator into seed.ts');