Files
scripts/docs/migrate-legacy-collections.md
devops 781bc459dd Add script to migrate legacy collections + cybertron-sentinel category
Documents and makes repeatable the Admin API writes for Fase 5 Etapa 2
sub-fase 1: assign real Medusa collections (Toy Story, Intensamente,
Lilo & Stitch, Universo Marvel, Reino de Frozen) to 9 legacy products,
and the missing "Figuras de accion" category to cybertron-sentinel.
Categories for the 17 legacy products were already correct and are
untouched.
2026-08-24 15:45:14 -05:00

4.1 KiB

Migración de colecciones legacy (Fase 5 / Etapa 2 / sub-fase 1, fix #2)

Script: scripts/migrate_legacy_collections.py.

Contexto

Al cerrar el fix #2 de la sub-fase 1 (categorías reales) se confirmó vía Store API (2026-08-24) que los 17 productos legacy ya tenían la category real correcta asignada desde una migración anterior, pero ningún producto tenía collection asignada — el campo estaba en null en los 27 productos existentes en ese momento (17 legacy + 1 Cybertron Sentinel + 9 demo). Sólo 2 colecciones existían en Medusa: "Universo Marvel" y "Reino de Frozen" (creadas en la auditoría de Etapa 1). Este script cierra esa brecha.

De paso asigna la categoría "Figuras de accion" a cybertron-sentinel-figura-de-coleccion-test-revalidate, el único de los 18 productos pre-existentes (no-demo) que quedó sin categoría en la migración anterior — no es uno de los "17 legacy", es el producto usado para validar el flujo de auto-refresh en el incidente Fase 4.

Fuera de alcance, por decisión explícita del usuario: metadata (brand/ageRange), precios, descripciones, imágenes. Solo categories/collection_id.

Mapeo aplicado

Colección Nueva/existente Productos (handle)
Toy Story nueva toy-story-5-rex, toy-story-5-buzz-lightyear, toy-story-5-jessie, toy-story-5-woody
Intensamente nueva intensamente-furia, intensamente-tristeza
Lilo & Stitch nueva angel-lilo-y-stitch
Universo Marvel existente (pcol_01M0PDFBDA0TXQNCX4E2AP8DJ5) mochilas-disney-coleccion-marvel, mochila-escolar-de-spider-man-..., disney-mochila-iron-man-..., mochila-de-disney-marvel-capitan-america-...
Reino de Frozen existente (pcol_01M0PDFBX1PT3ZA4KHJE6C9VKT) mochila-ligera-...-frozen-...
— (sin colección, por mapeo explícito del usuario) — minnie-y-mickey-mouse, mochila-pequena-bob-esponja, mochila-casual-...-bob-esponja-..., disney-mochila-de-poliester-..., mochila-escolar-estilo-britanico-...

Categoría faltante: cybertron-sentinel-figura-de-coleccion-test-revalidate → "Figuras de accion" (pcat_01M0PDF24BRVRKKMPMXCTY7QXJ).

Las 17 categorías legacy en sí no se tocan — se verificaron 1:1 contra el mapeo del usuario antes de correr este script y ya coincidían exactamente (ver memoria del proyecto project_fase5_etapa2_subfase1_categorias_2026_08_23.md).

Endpoints Admin API (Medusa v2) usados

  • GET /admin/collections?title=X — chequear si una colección ya existe.
  • POST /admin/collections — crear colección (title, handle).
  • POST /admin/collections/:id/products con body {"add": [...], "remove": []} — asignar productos a una colección.
  • POST /admin/product-categories/:id/products con body {"add": [...], "remove": []} — asignar productos a una categoría (mismo patrón confirmado en el fix #2 de categorías).

Confirmado que no existen en esta versión de Medusa: POST /admin/products/:id/categories (404), ni collection_id/category_ids en el body de PATCH /admin/products/:id (400).

Cómo correrlo

Requiere un JWT de admin (ADMIN_JWT) obtenido vía POST /auth/user/emailpass — no se persiste en este repo. El bloqueo del clasificador de auto-mode sobre escrituras en lote contra producción aplica aquí igual que en el fix #2 de categorías (ver memoria feedback_auto_mode_classifier_hard_blocks), así que el --apply lo corre el usuario directamente, no Claude:

export MEDUSA_BACKEND_URL=https://commerce.cruzcloud.net
export ADMIN_JWT=<token>

# 1. Verificar el plan sin escribir nada
python3 scripts/migrate_legacy_collections.py --dry-run

# 2. Ejecutar
python3 scripts/migrate_legacy_collections.py --apply

Rollback

Cada asignación es aditiva (add) sobre relaciones many-to-many, no destructiva de datos previos. Para revertir, llamar los mismos endpoints con {"remove": [...ids], "add": []} con los mismos product_id/collection_id/category_id documentados arriba. Las colecciones creadas ("Toy Story", "Intensamente", "Lilo & Stitch") se pueden borrar con DELETE /admin/collections/:id si hace falta deshacer la migración por completo.