# F-114 — Arquitectura: importar categorías de OpenCart sin duplicar

## Origen
Tabla legacy `oc_category_description` (PHPMyAdmin, MySQL) en `localhost:3306/admin_natural`,
consulta `SELECT category_id, name FROM oc_category_description WHERE language_id=1;` con 76 filas.

## Catálogo actual
- 5 raíces: `Alimentacion`, `Cosmetica e Higiene`, `Hogar y Mascotas`, `Limpieza Ecologica`, `Suplementos`.
- 7 hijos directos.
- 5 marcas: `BioSana`, `EcoVida`, `NaturGreen`, `SolNatural`, `TierraNatural`.

## Decisiones
1. **No crear un importador genérico desde MySQL**: no asumimos acceso de red a la base legacy.
   En su lugar, hardcodeamos la lista en un script de seed reproducible (`scripts/seed-legacy-categories.mjs`).
   Cuando llegue el momento de conectar al OpenCart real, un paso posterior puede volcar a JSON y alimentar el mismo script.
2. **Cada entrada va a donde corresponde**:
   - **Marcas** → `brands_brands`. Lista: SOLGAR, EL GRANERO INTEGRAL, A.VOGEL, BIOCOP, QBIO, LA FINESTRA SUL CIELO,
     CADIDIET, CHISVERT, DIETISUR, GOURMET BIO, GOURMET CASH, NUTRINAT, COMERCIAL GARZA, ARTESANÍA AGRÍCOLA,
     DAS BROT, DULCES LISSEN, LEMONPHARMA, VEKINE, NAAY BOTANICALS, LAMBERTS, YODETIENDAS, NATURCOSMETIKA,
     TONGIL, SALUD VIVA, GLOBO NATURA, BIOSPIRIT, NATURALMENTE MEDITERRANEO, NATURAL, VITAFOOD, PROVIDEEDORES.
   - **Categorías reales** → `categories_categories`. Incluye el resto.
3. **Normalización**: decodificar entidades HTML (`&amp;`, `&nbsp;`), trim, colapso de espacios, comparación case-insensitive.
4. **Deduplicación**:
   - Categoría: si existe una con el mismo `name` (normalizado, case-insensitive) → skip (no duplicar).
   - Categoría marca: si existe en `brands_brands` por `name` igual → skip.
   - Slug único: si el slug derivado ya existe, se numera (`aceites-2`, `aceites-3`, …).
5. **Padre de cada nueva categoría** (mapeo manual):
   - Por defecto cuelgan de la raíz `Alimentacion` salvo que indique lo contrario.
   - Mapeo específico (cat, parent):
     - 67 HERBALIST → Hierbas e Infusiones
     - 68 FOOD → Alimentacion
     - 69 COSMETICS → Cosmetica e Higiene
     - 70 DIET AND NUTRITION → Suplementos
     - 71 NUTS & SEEDS → Frutos Secos
     - 72 BREAD & PASTRIES → Alimentacion
     - 75 LEGUMES → Alimentacion
     - 76 FLOUR & CEREALS → Alimentacion
     - 77 PASTA & RICE → Alimentacion
     - 78 CREAMS & JAMS → Cremas
     - 79 FRUTAS Y VERDURAS → Alimentacion
     - 80 SUGAR & SWEETENERS → Alimentacion
     - 81 BEVERAGES → Alimentacion
     - 82 OIL AND VINEGAR → Aceites
     - 83 RAW FOOD → Alimentacion
     - 84 HIERBAS MEDICINALES → Hierbas e Infusiones
     - 85 SUPLEMENTS → Suplementos
     - 86 OILS & EXTRACTS → Aceites
     - 87 FACIAL → Cosmetica e Higiene
     - 88 CORPORAL → Cosmetica e Higiene
     - 89 ASEO PERSONAL → Cosmetica e Higiene
     - 90 HOME → Hogar y Mascotas
     - 91 MACROBIOTIC → Alimentacion
     - 93 SNACKS → Alimentacion
     - 95 BOOKS → Hogar y Mascotas (libros)
     - 97 FRESH PRODUCTS → Alimentacion
     - 102 WINE → Alimentacion
     - 103 BEER → Alimentacion
     - 104 VEGETAL MILKS → Alimentacion
     - 105 JUICES → Alimentacion
     - 106 SODAS → Alimentacion
     - 107 CHILDREN → Alimentacion
     - 108 BABYS & KIDS → Cosmetica e Higiene (cosmética infantil)
     - 115 TEA & INFUSIONS → Hierbas e Infusiones
     - 116 SPICE & CONDIMENTS → Alimentacion
     - 117 CHOCOLATE & SWEETS → Alimentacion
     - 127 PROVEEDORES → raíz (proveedores)
     - 129 CLEANING → Limpieza Ecologica
6. **Excluidos** (no son categorías):
   - `00 - SIN CODIGO`, `01 - PRODUCTOS DESCATALOGADOS`, `02 - PRODUCTOS RAPIDOS`: marcadores legacy, no importan.
7. **Idempotencia**: el script busca antes de insertar; se puede re-ejecutar sin crear duplicados.
8. **Lenguaje**: los nombres y los slugs se guardan tal cual aparecen en el legacy tras normalizar.

## Componentes
- `scripts/seed-legacy-categories.mjs`: CLI ejecutable que importa categorías/marcas.
- `src/modules/categories/legacy/legacy-catalog.ts` (helper en TS): define la lista, normalización, parent-mapping, dedup. Exportable para tests.
- `src/modules/categories/tests/legacy-catalog.test.ts`: tests de la normalización, slugificación, dedup, mapeo.
- README corto en `work/artifacts/F-114/README.md` con la salida esperada del seed.

## Tests
- Normalización: `&amp;`, `&nbsp;`, mayúsculas, espacios.
- Slugificación: minúsculas, guiones, signos.
- Deduplicación: case-insensitive y por slug.
- Mapeo: todas las entradas del legacy se clasifican en categoría/marca/excluido.
- Smoke itest opcional contra DB (marcado como such, no obligatorio).

## Fuera de alcance
- Sin importación de productos.
- Sin conexión al MySQL real.
- Sin traducciones (solo `language_id=1`).
