chore(seed): disable product and variant generation in seed.cjs
This commit is contained in:
1 parent
83a0b8834c
commit
a27743678c
2 files changed
+9
-138
No files matched your search
+2
-2
@@ -193,8 +193,8 @@ bun run prisma/seed.cjs
|
|||||||
```
|
```
|
||||||
|
|
||||||
ระบบจะสร้าง:
|
ระบบจะสร้าง:
|
||||||
- เมนูพื้นฐาน
|
- เมนูพื้นฐาน (Core Menus)
|
||||||
- ข้อมูลจำลอง (แบรนด์, สินค้า, กลิ่น)
|
- ข้อมูลพื้นฐาน (แบรนด์, หมวดหมู่ - ไม่ seed สินค้า)
|
||||||
- บัญชี Admin (`admin` / `homaroma123`)
|
- บัญชี Admin (`admin` / `homaroma123`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -51,40 +51,7 @@ const categoryConfigs = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
process.stdout.write('🚀 Starting Advanced Seeding (Products & Variants)...\n');
|
process.stdout.write('🚀 Starting System Seeding (Admin, Menus, Brands, Categories)...\n');
|
||||||
|
|
||||||
// Load or create category description files
|
|
||||||
const descriptionsDir = path.join(__dirname, 'descriptions');
|
|
||||||
if (!fs.existsSync(descriptionsDir)) {
|
|
||||||
fs.mkdirSync(descriptionsDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
const categoryDescriptions = {};
|
|
||||||
for (const config of categoryConfigs) {
|
|
||||||
const safeName = config.name.replace(/\s+/g, '_');
|
|
||||||
const descPath = path.join(descriptionsDir, `${safeName}.txt`);
|
|
||||||
|
|
||||||
// Auto-create with default template if not exists
|
|
||||||
if (!fs.existsSync(descPath)) {
|
|
||||||
const defaultDesc = `ผลิตภัณฑ์ ${config.name} กลิ่น {{brand}} มอบประสบการณ์ความหอมที่ผ่อนคลายและสดชื่น ช่วยให้บรรยากาศในห้องของคุณน่าอยู่มากยิ่งขึ้น`;
|
|
||||||
fs.writeFileSync(descPath, defaultDesc, 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryDescriptions[config.name] = fs.readFileSync(descPath, 'utf8');
|
|
||||||
|
|
||||||
// Auto-create category details
|
|
||||||
const detailsDir = path.join(__dirname, 'details');
|
|
||||||
if (!fs.existsSync(detailsDir)) {
|
|
||||||
fs.mkdirSync(detailsDir);
|
|
||||||
}
|
|
||||||
const detailPath = path.join(detailsDir, `${safeName}.txt`);
|
|
||||||
if (!fs.existsSync(detailPath)) {
|
|
||||||
const defaultDetail = `รายละเอียดฉบับเต็มของ ${config.name} กลิ่น {{brand}}\n- ส่วนประกอบนำเข้าคุณภาพสูง\n- กระจายความหอมได้ยาวนานในห้อง\n- ปลอดภัยต่อสุขภาพและเหมาะสำหรับทุกคนในครอบครัว`;
|
|
||||||
fs.writeFileSync(detailPath, defaultDetail, 'utf8');
|
|
||||||
}
|
|
||||||
categoryConfigs[config.name] = categoryConfigs[config.name] || {};
|
|
||||||
categoryConfigs[config.name].detailsTemplate = fs.readFileSync(detailPath, 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0. Seed Admin User
|
// 0. Seed Admin User
|
||||||
await seedAdmin(prisma);
|
await seedAdmin(prisma);
|
||||||
@@ -131,119 +98,23 @@ async function main() {
|
|||||||
update: {},
|
update: {},
|
||||||
create: { name: config.name }
|
create: { name: config.name }
|
||||||
});
|
});
|
||||||
categories.push({ ...c, allowedSizes: config.sizes, priceMap: config.priceMap, detailsTemplate: categoryConfigs[config.name].detailsTemplate });
|
categories.push(c);
|
||||||
}
|
}
|
||||||
process.stdout.write(`✅ Seeded ${categories.length} Categories.\n`);
|
process.stdout.write(`✅ Seeded ${categories.length} Categories.\n`);
|
||||||
|
|
||||||
// 2. Cross Brands x Categories to create Products
|
// Skipped product & variant seeding per configuration
|
||||||
process.stdout.write('📦 Generating Products and Variants...\n');
|
|
||||||
let productCount = 0;
|
|
||||||
let variantCount = 0;
|
|
||||||
|
|
||||||
for (const brand of brands) {
|
|
||||||
for (const category of categories) {
|
|
||||||
const productName = `${brand.name} ${category.name}`;
|
|
||||||
|
|
||||||
// Get category description template and replace {{brand}}
|
|
||||||
let productDescription = categoryDescriptions[category.name] || `Product ${brand.name} in category ${category.name}`;
|
|
||||||
productDescription = productDescription.replace(/{{brand}}/g, brand.name);
|
|
||||||
productDescription = productDescription.replace(/{{scent}}/g, brand.name);
|
|
||||||
|
|
||||||
let productDetails = category.detailsTemplate || '';
|
|
||||||
productDetails = productDetails.replace(/{{brand}}/g, brand.name);
|
|
||||||
productDetails = productDetails.replace(/{{scent}}/g, brand.name);
|
|
||||||
|
|
||||||
// Upsert Product without unique constraint on brandId + categoryId
|
|
||||||
let product = await prisma.product.findFirst({
|
|
||||||
where: { brandId: brand.id, categoryId: category.id }
|
|
||||||
});
|
|
||||||
if (product) {
|
|
||||||
product = await prisma.product.update({
|
|
||||||
where: { id: product.id },
|
|
||||||
data: {
|
|
||||||
name: productName,
|
|
||||||
description: productDescription,
|
|
||||||
details: productDetails
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
product = await prisma.product.create({
|
|
||||||
data: {
|
|
||||||
name: productName,
|
|
||||||
brandId: brand.id,
|
|
||||||
categoryId: category.id,
|
|
||||||
description: productDescription,
|
|
||||||
details: productDetails,
|
|
||||||
options: category.allowedSizes.length > 0 ? [{ name: "Size", values: category.allowedSizes }] : []
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
productCount++;
|
|
||||||
|
|
||||||
// 3. Create Default Product Image
|
|
||||||
// Using existing category-based image paths as initial seed data
|
|
||||||
const defaultImagePath = category.name === 'Oil Ozone' || category.name === 'Aroma Oil' || category.name === 'Car Diffuser'
|
|
||||||
? '/images/oil_ozone.png'
|
|
||||||
: '/images/reed_diffuser.png';
|
|
||||||
|
|
||||||
await prisma.productImage.upsert({
|
|
||||||
where: { id: (product.id * 10) + 1 }, // Pseudo-stable ID for seed
|
|
||||||
update: { url: defaultImagePath },
|
|
||||||
create: {
|
|
||||||
id: (product.id * 10) + 1,
|
|
||||||
productId: product.id,
|
|
||||||
url: defaultImagePath,
|
|
||||||
order: 0
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
// Fallback for cases where ID might conflict or upsert on non-unique field
|
|
||||||
return prisma.productImage.create({
|
|
||||||
data: {
|
|
||||||
productId: product.id,
|
|
||||||
url: defaultImagePath,
|
|
||||||
order: 0
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 4. Create Variants (Sizes) with prices from priceMap
|
|
||||||
for (const size of category.allowedSizes) {
|
|
||||||
const price = category.priceMap?.[size] ?? 0;
|
|
||||||
await prisma.productVariant.upsert({
|
|
||||||
where: {
|
|
||||||
productId_option1_option2_option3: {
|
|
||||||
productId: product.id,
|
|
||||||
option1: size,
|
|
||||||
option2: "",
|
|
||||||
option3: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: { price }, // อัปเดตราคาเมื่อ re-seed
|
|
||||||
create: {
|
|
||||||
productId: product.id,
|
|
||||||
sku: `${brand.id}-${category.id}-${size}`.replace(/\s+/g, '-').toUpperCase(),
|
|
||||||
option1: size,
|
|
||||||
option2: "",
|
|
||||||
option3: "",
|
|
||||||
price: price
|
|
||||||
}
|
|
||||||
});
|
|
||||||
variantCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
process.stdout.write(`.`); // Progress indicator
|
|
||||||
}
|
|
||||||
|
|
||||||
process.stdout.write(`\n✨ Seeding Complete!\n`);
|
process.stdout.write(`\n✨ Seeding Complete!\n`);
|
||||||
process.stdout.write(`📊 Summary:\n`);
|
process.stdout.write(`📊 Summary:\n`);
|
||||||
|
process.stdout.write(` - Admin: 1 (admin / homaroma123)\n`);
|
||||||
|
process.stdout.write(` - Menus: ${coreMenus.length}\n`);
|
||||||
process.stdout.write(` - Brands: ${brands.length}\n`);
|
process.stdout.write(` - Brands: ${brands.length}\n`);
|
||||||
process.stdout.write(` - Categories: ${categories.length}\n`);
|
process.stdout.write(` - Categories: ${categories.length}\n`);
|
||||||
process.stdout.write(` - Products: ${productCount}\n`);
|
process.stdout.write(` - Products: 0 (Skipped per configuration)\n`);
|
||||||
process.stdout.write(` - Variants: ${variantCount}\n`);
|
|
||||||
// Fix PostgreSQL sequence desync for tables where we hardcoded IDs
|
// Fix PostgreSQL sequence desync for tables where we hardcoded IDs
|
||||||
process.stdout.write('🔄 Resetting sequences for hardcoded ID tables...\n');
|
process.stdout.write('🔄 Resetting sequences for hardcoded ID tables...\n');
|
||||||
await prisma.$executeRawUnsafe(`SELECT setval('"MenuItem_id_seq"', COALESCE((SELECT MAX(id) FROM "MenuItem") + 1, 1), false);`);
|
await prisma.$executeRawUnsafe(`SELECT setval('"MenuItem_id_seq"', COALESCE((SELECT MAX(id) FROM "MenuItem") + 1, 1), false);`);
|
||||||
await prisma.$executeRawUnsafe(`SELECT setval('"ProductImage_id_seq"', COALESCE((SELECT MAX(id) FROM "ProductImage") + 1, 1), false);`);
|
|
||||||
process.stdout.write('✅ Sequences reset successfully.\n');
|
process.stdout.write('✅ Sequences reset successfully.\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user