import 'dotenv/config'; import { prisma } from '../src/prisma-client.js'; function normalizeText(value) { return String(value ?? '').replaceAll(/\s+/g, ' ').trim(); } function sentenceCase(value) { if (!value) { return value; } return value[0].toUpperCase() + value.slice(1); } function parseProductName(name) { const normalizedName = normalizeText(name); const [productTypeRaw] = normalizedName.split(','); const sizeMatch = normalizedName.match(/(\d+)\s*[xх*]\s*(\d+)\s*м/i); const thicknessMatch = normalizedName.match(/(\d+)\s*мкм/i); const sleeveMatch = normalizedName.match(/втулка\s+([^,]+)/i); const quantityMatch = normalizedName.match(/короб\s+([^,]+)/i); if (!productTypeRaw || !sizeMatch || !thicknessMatch || !sleeveMatch || !quantityMatch) { throw new Error(`Unable to parse product name: ${name}`); } return { productType: normalizeText(productTypeRaw).toLowerCase(), widthMm: Number.parseInt(sizeMatch[1] ?? '', 10), lengthM: Number.parseInt(sizeMatch[2] ?? '', 10), thicknessMicron: Number.parseInt(thicknessMatch[1] ?? '', 10), sleeveBrand: normalizeText(sleeveMatch[1]).toLowerCase(), quantityPerBox: normalizeText(quantityMatch[1]), }; } const products = await prisma.product.findMany({ where: { isActive: true, OR: [ { productType: null }, { widthMm: null }, { lengthM: null }, { thicknessMicron: null }, { sleeveBrand: null }, { quantityPerBox: null }, ], }, select: { id: true, sku: true, name: true, }, }); for (const product of products) { const parsed = parseProductName(product.name); await prisma.product.update({ where: { id: product.id }, data: { productType: sentenceCase(parsed.productType), widthMm: parsed.widthMm, lengthM: parsed.lengthM, thicknessMicron: parsed.thicknessMicron, sleeveBrand: parsed.sleeveBrand, quantityPerBox: parsed.quantityPerBox, }, }); } console.log(`Backfilled ${products.length} products.`); await prisma.$disconnect();