feat(F-048): completed feature

This commit is contained in:
chattie
2026-08-19 07:17:14 +02:00
parent 8ee1938af9
commit 835ab66eda
187 changed files with 12361 additions and 1065 deletions

View File

@@ -51,7 +51,12 @@ async function seed(client) {
await sql(client, 'DELETE FROM catalog_product_variants', [], 'clear-variants');
await sql(client, 'DELETE FROM catalog_product_categories', [], 'clear-prod-cats');
await sql(client, 'DELETE FROM catalog_products', [], 'clear-products');
await sql(client, "DELETE FROM categories_categories WHERE parent_id IS NOT NULL", [], 'clear-children');
await sql(
client,
'DELETE FROM categories_categories WHERE parent_id IS NOT NULL',
[],
'clear-children',
);
await sql(client, 'DELETE FROM categories_categories', [], 'clear-categories');
await sql(client, 'DELETE FROM brands_brands', [], 'clear-brands');
await sql(client, 'DELETE FROM shipping_methods', [], 'clear-methods');
@@ -81,12 +86,15 @@ async function seed(client) {
const children = catData.filter((c) => c.parentSlug);
for (const cat of [...parents, ...children]) {
const parentId = cat.parentSlug ? catBySlug[cat.parentSlug] : null;
await sql(client,
await sql(
client,
'INSERT INTO categories_categories (id, parent_id, name, slug, seo_title) VALUES ($1,$2,$3,$4,$5) ON CONFLICT (slug) DO UPDATE SET name=EXCLUDED.name, seo_title=EXCLUDED.seo_title',
[randomUUID(), parentId, cat.name, cat.slug, cat.name],
`cat-${cat.slug}`
`cat-${cat.slug}`,
);
const r = await client.query('SELECT id FROM categories_categories WHERE slug = $1', [cat.slug]);
const r = await client.query('SELECT id FROM categories_categories WHERE slug = $1', [
cat.slug,
]);
if (r.rows[0]) catBySlug[cat.slug] = r.rows[0].id;
}
console.log(`+ ${catData.length} categories`);
@@ -102,10 +110,11 @@ async function seed(client) {
];
for (const brand of brandData) {
await sql(client,
await sql(
client,
'INSERT INTO brands_brands (id, name, slug, seo_title) VALUES ($1,$2,$3,$4) ON CONFLICT (slug) DO UPDATE SET name=EXCLUDED.name, seo_title=EXCLUDED.seo_title',
[randomUUID(), brand.name, brand.slug, brand.name],
`brand-${brand.slug}`
`brand-${brand.slug}`,
);
const r = await client.query('SELECT id FROM brands_brands WHERE slug = $1', [brand.slug]);
if (r.rows[0]) brandBySlug[brand.slug] = r.rows[0].id;
@@ -114,25 +123,112 @@ async function seed(client) {
// ── 3. Products + variants + prices + stock ───────────────────────────
const productData = [
{ name: 'Almendras Crudas Ecologicas', slug: 'almendras-crudas-ecologicas', brandSlug: 'ecovida', catSlug: 'frutos-secos', price: 895, vat: 'general' },
{ name: 'Aceite de Oliva Virgen Extra Bio', slug: 'aceite-oliva-virgen-extra-bio', brandSlug: 'naturgreen', catSlug: 'aceites', price: 1290, vat: 'general' },
{ name: 'Te Verde Matcha Premium', slug: 'te-verde-matcha-premium', brandSlug: 'biosana', catSlug: 'hierbas-infusiones', price: 1590, vat: 'general' },
{ name: 'Vitamina D3 + K2', slug: 'vitamina-d3-k2', brandSlug: 'verdepura', catSlug: 'vitaminas', price: 1890, vat: 'reduced' },
{ name: 'Proteina Guisante Ecologica', slug: 'proteina-guisante-ecologica', brandSlug: 'tierranatural', catSlug: 'proteinas', price: 2490, vat: 'reduced' },
{ name: 'Complejo B Natural', slug: 'complejo-b-natural', brandSlug: 'ecovida', catSlug: 'vitaminas', price: 1190, vat: 'reduced' },
{ name: 'Crema Facial Hidratante Aloe Vera', slug: 'crema-facial-aloe-vera', brandSlug: 'solnatural', catSlug: 'cremas', price: 2190, vat: 'general' },
{ name: 'Jabon Negro Africano', slug: 'jabon-negro-africano', brandSlug: 'biosana', catSlug: 'jabones', price: 790, vat: 'general' },
{ name: 'Serum Antioxidante Rosa Mosqueta', slug: 'serum-rosa-mosqueta', brandSlug: 'naturgreen', catSlug: 'cremas', price: 2690, vat: 'general' },
{ name: 'Detergente Ecologico Ropa', slug: 'detergente-ecologico-ropa', brandSlug: 'verdepura', catSlug: 'limpieza-ecologica', price: 990, vat: 'general' },
{ name: 'Limpiador Multiusos Bio', slug: 'limpiador-multiusos-bio', brandSlug: 'tierranatural', catSlug: 'limpieza-ecologica', price: 890, vat: 'general' },
{ name: 'Desinfectante Natural Superficies', slug: 'desinfectante-natural-superficies', brandSlug: 'solnatural', catSlug: 'limpieza-ecologica', price: 1190, vat: 'general' },
{
name: 'Almendras Crudas Ecologicas',
slug: 'almendras-crudas-ecologicas',
brandSlug: 'ecovida',
catSlug: 'frutos-secos',
price: 895,
vat: 'general',
},
{
name: 'Aceite de Oliva Virgen Extra Bio',
slug: 'aceite-oliva-virgen-extra-bio',
brandSlug: 'naturgreen',
catSlug: 'aceites',
price: 1290,
vat: 'general',
},
{
name: 'Te Verde Matcha Premium',
slug: 'te-verde-matcha-premium',
brandSlug: 'biosana',
catSlug: 'hierbas-infusiones',
price: 1590,
vat: 'general',
},
{
name: 'Vitamina D3 + K2',
slug: 'vitamina-d3-k2',
brandSlug: 'verdepura',
catSlug: 'vitaminas',
price: 1890,
vat: 'reduced',
},
{
name: 'Proteina Guisante Ecologica',
slug: 'proteina-guisante-ecologica',
brandSlug: 'tierranatural',
catSlug: 'proteinas',
price: 2490,
vat: 'reduced',
},
{
name: 'Complejo B Natural',
slug: 'complejo-b-natural',
brandSlug: 'ecovida',
catSlug: 'vitaminas',
price: 1190,
vat: 'reduced',
},
{
name: 'Crema Facial Hidratante Aloe Vera',
slug: 'crema-facial-aloe-vera',
brandSlug: 'solnatural',
catSlug: 'cremas',
price: 2190,
vat: 'general',
},
{
name: 'Jabon Negro Africano',
slug: 'jabon-negro-africano',
brandSlug: 'biosana',
catSlug: 'jabones',
price: 790,
vat: 'general',
},
{
name: 'Serum Antioxidante Rosa Mosqueta',
slug: 'serum-rosa-mosqueta',
brandSlug: 'naturgreen',
catSlug: 'cremas',
price: 2690,
vat: 'general',
},
{
name: 'Detergente Ecologico Ropa',
slug: 'detergente-ecologico-ropa',
brandSlug: 'verdepura',
catSlug: 'limpieza-ecologica',
price: 990,
vat: 'general',
},
{
name: 'Limpiador Multiusos Bio',
slug: 'limpiador-multiusos-bio',
brandSlug: 'tierranatural',
catSlug: 'limpieza-ecologica',
price: 890,
vat: 'general',
},
{
name: 'Desinfectante Natural Superficies',
slug: 'desinfectante-natural-superficies',
brandSlug: 'solnatural',
catSlug: 'limpieza-ecologica',
price: 1190,
vat: 'general',
},
];
for (let pi = 0; pi < productData.length; pi++) {
const p = productData[pi];
const brandId = brandBySlug[p.brandSlug];
const catId = catBySlug[p.catSlug];
if (!brandId || !catId) { console.warn(` Skipping ${p.slug}: missing brand or cat`); continue; }
if (!brandId || !catId) {
console.warn(` Skipping ${p.slug}: missing brand or cat`);
continue;
}
const productId = randomUUID();
const variantId = randomUUID();
@@ -140,50 +236,58 @@ async function seed(client) {
const ean = `590123412345${String(pi + 1).padStart(2, '0')}`;
const desc = `${p.name} de primera calidad. Producto 100% natural y ecologico.`;
await sql(client,
await sql(
client,
'INSERT INTO catalog_products (id, brand_id, name, slug, state, seo_title, description) VALUES ($1,$2,$3,$4,$5,$6,$7) ON CONFLICT (slug) DO UPDATE SET name=EXCLUDED.name, brand_id=EXCLUDED.brand_id, description=EXCLUDED.description',
[productId, brandId, p.name, p.slug, 'active', p.name, desc],
`product-${p.slug}`
`product-${p.slug}`,
);
await sql(client,
await sql(
client,
'INSERT INTO catalog_product_categories (product_id, category_id) VALUES ($1,$2) ON CONFLICT DO NOTHING',
[productId, catId],
`prodcat-${p.slug}`
`prodcat-${p.slug}`,
);
await sql(client,
await sql(
client,
'INSERT INTO catalog_product_variants (id, product_id, sku, ean) VALUES ($1,$2,$3,$4) ON CONFLICT (sku) DO UPDATE SET ean=EXCLUDED.ean',
[variantId, productId, sku, ean],
`variant-${sku}`
`variant-${sku}`,
);
await sql(client,
await sql(
client,
'INSERT INTO pricing_variant_prices (variant_id, vat_rate, net_unit_amount_cents) VALUES ($1,$2,$3) ON CONFLICT (variant_id) DO UPDATE SET net_unit_amount_cents=EXCLUDED.net_unit_amount_cents, vat_rate=EXCLUDED.vat_rate',
[variantId, p.vat, p.price],
`price-${sku}`
`price-${sku}`,
);
await sql(client,
await sql(
client,
'INSERT INTO inventory_stock (variant_id, available, reserved) VALUES ($1,$2,$3) ON CONFLICT (variant_id) DO UPDATE SET available=EXCLUDED.available, reserved=EXCLUDED.reserved',
[variantId, 25, 0],
`stock-${sku}`
`stock-${sku}`,
);
}
console.log(`+ ${productData.length} products (variants, prices, stock)`);
// ── 4. Shipping ───────────────────────────────────────────────────
const zoneId = randomUUID();
await sql(client,
await sql(
client,
'INSERT INTO shipping_zones (id, name, country, postal_code_prefix) VALUES ($1,$2,$3,$4) ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name',
[zoneId, 'Espania Peninsular', 'ES', null],
'zone-es'
'zone-es',
);
await sql(client,
await sql(
client,
'INSERT INTO shipping_methods (id, zone_id, name, base_cost_cents, free_shipping_threshold_cents) VALUES ($1,$2,$3,$4,$5)',
[randomUUID(), zoneId, 'Estandar', 499, 4900],
'method-std'
'method-std',
);
await sql(client,
await sql(
client,
'INSERT INTO shipping_methods (id, zone_id, name, base_cost_cents, free_shipping_threshold_cents) VALUES ($1,$2,$3,$4,$5)',
[randomUUID(), zoneId, 'Express 24h', 899, null],
'method-express'
'method-express',
);
console.log('+ 1 shipping zone + 2 methods');