Files
apollo-backend/scripts/backfill-product-specs.js
2026-04-03 15:15:57 +07:00

76 lines
2.0 KiB
JavaScript
Raw Permalink 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.

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();