fix(seed): handle duplicate product barcodes safely with try-catch in seed-products.ts
Some checks failed
Deploy Canina / deploy (push) Has been cancelled

This commit is contained in:
parsa aghaei 2026-07-29 15:21:41 +03:30
parent 485c6bfec6
commit e1fb300b87

View File

@ -204,56 +204,84 @@ export async function main() {
const RX_PRODUCTS = ['canina-canhydrox-gag', 'canina-petvital-gag', 'canina-herz-vital', 'canina-petvital-arthro-tabletten', 'canina-immun-booster', 'canina-petvital-bio-aktivator', 'canina-rinderblut-pulver', 'canina-velox-gelenkenergie'];
const requiresRx = RX_PRODUCTS.includes(baseSlug);
const product = await prisma.product.upsert({
where: { artNo },
update: {
barcode,
slug,
productGroup: baseSlug,
nameFa,
nameEn,
scientificTagline: PRODUCT_TAGLINES_MAP[baseSlug] || null,
description: cleanDesc,
shortDescription: cleanShortDesc,
ingredients: cleanIngredients,
categoryId: category.id,
categorySlug: category.slug,
priceValue: sellPrice,
wholesalePrice: Math.round(sellPrice * 0.7),
requiresRx,
buyPrice,
priceDisplay,
unit,
packageSize,
dosageLogic: cleanDosage,
suitableFor,
imageUrl: getProductImageUrl(baseSlug),
},
create: {
artNo,
barcode,
slug,
productGroup: baseSlug,
nameFa,
nameEn,
scientificTagline: PRODUCT_TAGLINES_MAP[baseSlug] || null,
description: cleanDesc,
shortDescription: cleanShortDesc,
ingredients: cleanIngredients,
categoryId: category.id,
categorySlug: category.slug,
priceValue: sellPrice,
wholesalePrice: Math.round(sellPrice * 0.7),
requiresRx,
buyPrice,
priceDisplay,
unit,
packageSize,
dosageLogic: cleanDosage,
suitableFor,
imageUrl: getProductImageUrl(baseSlug),
try {
const product = await prisma.product.upsert({
where: { artNo },
update: {
barcode,
slug,
productGroup: baseSlug,
nameFa,
nameEn,
scientificTagline: PRODUCT_TAGLINES_MAP[baseSlug] || null,
description: cleanDesc,
shortDescription: cleanShortDesc,
ingredients: cleanIngredients,
categoryId: category.id,
categorySlug: category.slug,
priceValue: sellPrice,
wholesalePrice: Math.round(sellPrice * 0.7),
requiresRx,
buyPrice,
priceDisplay,
unit,
packageSize,
dosageLogic: cleanDosage,
suitableFor,
imageUrl: getProductImageUrl(baseSlug),
},
create: {
artNo,
barcode,
slug,
productGroup: baseSlug,
nameFa,
nameEn,
scientificTagline: PRODUCT_TAGLINES_MAP[baseSlug] || null,
description: cleanDesc,
shortDescription: cleanShortDesc,
ingredients: cleanIngredients,
categoryId: category.id,
categorySlug: category.slug,
priceValue: sellPrice,
wholesalePrice: Math.round(sellPrice * 0.7),
requiresRx,
buyPrice,
priceDisplay,
unit,
packageSize,
dosageLogic: cleanDosage,
suitableFor,
imageUrl: getProductImageUrl(baseSlug),
}
});
// Seed ingredients
await prisma.productIngredient.deleteMany({ where: { productId: product.id } });
if (cleanIngredients) {
const parts = cleanIngredients.split(/[،,]/).map((s: string) => s.trim()).filter(Boolean);
const meaningful = parts.slice(0, 20);
for (const ing of meaningful) {
const truncated = ing.substring(0, 150);
if (truncated.length > 0) {
await prisma.productIngredient.create({
data: { productId: product.id, ingredient: truncated }
});
}
}
}
});
// Seed symptoms
await prisma.productSymptom.deleteMany({ where: { productId: product.id } });
const symptomsList = PRODUCT_SYMPTOMS_MAP[baseSlug] || [];
for (const sym of symptomsList) {
await prisma.productSymptom.create({
data: { productId: product.id, symptom: sym }
});
}
} catch (err: any) {
console.warn(`[Seed] Warning upserting product ${artNo}:`, err.message || err);
}
// Seed ingredients
await prisma.productIngredient.deleteMany({ where: { productId: product.id } });