← Arquitectura por épica

FT-FLU-04 · Carga masiva de productos por archivo

Arquitectura del Nuevo PIM por épica · corte del 18-oct-2026

Propuesta del TL: no sustituye la spec de cada épica

Actualizado el 18-oct-2026. Primera versión de la arquitectura de esta épica.

Qué responde. Cómo funciona por dentro FT-FLU-04: qué piezas participan, en qué orden hablan, qué APIs hay que construir con su request y su response, y qué le entrega a la épica siguiente.

Para quién. Los equipos que van a construir la épica, QA y arquitectura.

Estado. [Propuesta] del TL del Nuevo PIM, 18-oct-2026, construida sobre ADR-12. La spec de cada épica dice el qué; estas páginas, el cómo.

Fuente. docs/arquitectura/por-epica/epicas/FT-FLU-04.json, generada con generar.py; la ficha de la épica es trazabilidad/features/FT-FLU-04-carga-masiva-productos-por-archivo.md.

En 30 segundos

Un seller o proveedor con cientos o miles de productos baja una plantilla de Excel por categoría y negocio, la llena fuera de línea y la sube. El PIM le da al momento un número de carga, valida todo en segundo plano (estructura, listas, obligatorios, lista negra y si ya existe) y al final le entrega un reporte por renglón, haya o no errores. Cada renglón válido nace como propuesta en Borrador, igual que si la hubiera capturado en pantalla.

  • Módulo dueño: MS-02 Producto. También participan: MS-01 Catálogo, MS-06 Evaluación, MS-14 Avisos y ayuda.
  • Etapa 0 · Entrada. Recibe «PE-C · Catálogo vigente», «PE-T · Usuario con permisos y bitácora» y entrega «PE-1 · Propuesta en Borrador».
  • APIs: construye 8 y usa 7 que construyen otras épicas.
  • Eventos: publica 4 y consume 1.

1. Dónde encaja

Recibe

DeQué
PE-C · Catálogo vigenteLa vista efectiva de cada plantilla por negocio: atributos, capa de obligatoriedad, listas cerradas y reglas de marca.
PE-T · Usuario con permisos y bitácoraEl seller o proveedor identificado por el BFF, con sus negocios y su permiso de alta.
FT-PLT-06 · Configuración de atributos por plantilla y por negocio…Los tres niveles de obligatoriedad por negocio (obligatorio, recomendado, opcional) que pintan los colores de la plantilla.
FT-RAC-01 · Motor de validación en línea y candados de datos…Las validaciones de tipo, lista, longitud y obligatorios, las mismas que corren en la pantalla.
FT-FLU-05 · Reglas de negocio en la carga masivaLa decisión de cada renglón: crear, ya existe con su acción (multioferta o stock out) o bloqueado, con el texto para el reporte.
FT-ARQ-01 · Núcleo headlessLa alta completa en un paso de MS-02, con origen BULK y envío al confirmar.
FT-PRD-03 · EANLa misma revisión de EAN, renglón por renglón: formato, dígito verificador, exentos y si ya existe en su negocio.
FT-PLT-10 · Fachada v1 compatible con P360 para Entrada Única y ForoLa revisión de plantilla y sección por renglón para la carga masiva (API-BFF-104), igual que ValidateTemplateSection.

Entrega

AQué
PE-1 · Propuesta en BorradorCada renglón válido nace como propuesta en Borrador con origen BULK, su plantilla, su dueño y la evaluación de MS-06 guardada; si trae completos los obligatorios de su negocio, se envía en la misma confirmación y queda En revisión.
FT-FLU-05 · Reglas de negocio en la carga masivaLos renglones ya revisados en estructura, tipos y listas, en bloques de hasta 500 con su rowRef, para evaluar lista negra, coincidencias y decisión por negocio.
FT-FLU-06 · Plantilla en línea para carga y enriquecimiento masivoLa recepción asíncrona, el trabajo de carga y el reporte por renglón, que la plantilla en línea reutiliza.
FT-PRD-10 · Catalogación por API del proveedor o sellerEl mismo trabajo de carga para los lotes que llegan por la API de terceros.

Cambios de estado que hace

TransiciónDe → aCuándo
T01Inicio → BorradorEl proveedor o seller guarda por primera vez (pantalla, archivo, plantilla en línea o API).
T03Borrador → En revisiónEnvía con los obligatorios completos.

Tareas que abre o cierra: Validación automática.

2. Diagrama de contexto

Quién participa y cómo se conecta. Las pantallas llegan por el BFF del portal, que valida el token y compone; cada módulo vuelve a validar el token y decide sus permisos con los roles de MS-13.

🟩 Verde: nuevo, se construye · 🟦 Azul: ya existe y se queda, se reutiliza su código · 🟧 Naranja: temporal o se retira (se apaga en R3) · ⬜ Gris: sistema externo · ★ módulo dueño

Nuevo PIM · un solo sistema

Pantallas y sistemas

Personas

Pantalla de carga masiva
Revisar plantilla y sección por rengl…

Bajar la plantilla de carga
Subir una carga masiva de producto
y 5 más

Vista efectiva de una plantilla por n…

Guarda el archivo original y encola l…

Evaluar los renglones de una carga ma…
Resultado de una evaluación masiva

EVALUATION_DONE

PRODUCT_CREATED
PRODUCT_UPDATED
y 1 más

Mandar un aviso explícito

Seller

Proveedor

Entrada Única · Vendor Center

BFF del portal

★ MS-02 Producto

MS-01 Catálogo

MS-06 Evaluación

MS-14 Avisos y ayuda

Base pim

Eventos

Archivos e imágenes

Contexto de FT-FLU-04

3. Diagrama de flujo

El camino principal, paso por paso. Cuando una pantalla llama a un módulo se ven dos flechas: la pantalla al BFF y el BFF al módulo. Los eventos salen del outbox del módulo después de guardar; quien los consume ignora los repetidos.

MS-14 Avisos y ayudaBase·pimEventosMS-06 EvaluaciónArchivosMS-01 CatálogoMS-02 ProductoEntrada Única · Vendor CenterMS-14 Avisos y ayudaBase·pimEventosMS-06 EvaluaciónArchivosMS-01 CatálogoMS-02 ProductoEntrada Única · Vendor CenterSellerBFF1. Abre la carga masiva y elige su negocio2. Pide la pantalla con sus categorías habitualesGET /bff/v1/bulk-loads/start3. Revisa que cada plantilla esté ligada a su secciónPOST /bff/v1/catalog/template-section-checks4. Baja la plantilla de hasta cinco categoríasGET /api/v2/product-imports/profiles/{p}/template5. Lee la vista efectiva de cada plantillaGET /api/v2/taxonomies/PRODUCT/nodes/{id}/effective6. Sube el archivo lleno y recibe el ID de cargaPOST /api/v2/product-imports7. Guarda el archivo original y encola la carga8. Manda a evaluar los renglones bien formadosPOST /api/v2/evaluations/batches9. Entrega la evaluación terminada de cada bloqueEVALUATION_DONE10. Lee la decisión de cada renglónGET /api/v2/evaluations/batches/{batchId}11. Confirma los renglones válidos tras ver el estatusPOST /api/v2/product-imports/{id}/apply12. Crea las propuestas en Borrador y envía las completas13. Avisa cada propuesta nueva con origen BULKPRODUCT_CREATED14. Avisa que terminó y deja el reporte por renglónPOST /internal/notifications/messagesSellerBFF
Flujo principal de FT-FLU-04
Los pasos en texto
PasoDeAQué haceAPI o evento
1SellerEntrada Única · Vendor CenterAbre la carga masiva y elige su negocio—
2Entrada Única · Vendor CenterBFF del portalPide la pantalla con sus categorías habitualesAPI-BFF-203
3Entrada Única · Vendor CenterBFF del portalRevisa que cada plantilla esté ligada a su secciónAPI-BFF-104
4Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Baja la plantilla de hasta cinco categoríasAPI-02-045
5MS-02 ProductoMS-01 CatálogoLee la vista efectiva de cada plantillaAPI-01-028
6Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Sube el archivo lleno y recibe el ID de cargaAPI-02-046
7MS-02 ProductoArchivos e imágenes (almacén y CDN)Guarda el archivo original y encola la carga—
8MS-02 ProductoMS-06 EvaluaciónManda a evaluar los renglones bien formadosAPI-06-002
9EventosMS-02 ProductoEntrega la evaluación terminada de cada bloquecatalog.validation.result/EVALUATION_DONE
10MS-02 ProductoMS-06 EvaluaciónLee la decisión de cada renglónAPI-06-003
11Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Confirma los renglones válidos tras ver el estatusAPI-02-047
12MS-02 ProductoBase pimCrea las propuestas en Borrador y envía las completas—
13MS-02 ProductoEventosAvisa cada propuesta nueva con origen BULKcatalog.product.changed/PRODUCT_CREATED
14MS-02 ProductoMS-14 Avisos y ayudaAvisa que terminó y deja el reporte por renglónAPI-14-005

3.1 Plantilla prellenada para corregir

EventosBase·pimMS-02 ProductoEntrada Única · Vendor CenterEventosBase·pimMS-02 ProductoEntrada Única · Vendor CenterSellerBFF1. Busca sus productos por SKU o EAN2. Busca los productos del sellerPOST /api/v2/products/search3. Baja la plantilla prellenada con sus datosGET /api/v2/product-imports/profiles/{p}/template4. Sube el archivo corregidoPOST /api/v2/product-imports5. Confirma los cambios válidosPOST /api/v2/product-imports/{id}/apply6. Aplica sólo las celdas que cambiaron7. Avisa el cambio con origen BULKPRODUCT_UPDATEDSellerBFF
Plantilla prellenada para corregir

3.2 Mercaderías por la misma carga

EventosBase·pimMS-06 EvaluaciónMS-02 ProductoEntrada Única · Vendor CenterEventosBase·pimMS-06 EvaluaciónMS-02 ProductoEntrada Única · Vendor CenterProveedorBFF1. Sube su archivo de Mercaderías2. Sube la carga del negocio MERPOST /api/v2/product-imports3. Evalúa EAN usados y reglas de MercaderíasPOST /api/v2/evaluations/batches4. Confirma los renglones válidosPOST /api/v2/product-imports/{id}/apply5. Crea, envía y abre el visto bueno de Compras6. Avisa que pasaron a En revisiónSTATUS_CHANGEDProveedorBFF
Mercaderías por la misma carga

3.3 Reporte por renglón al terminar

Entrada Única · Vendor CenterMS-14 Avisos y ayudaMS-02 ProductoEntrada Única · Vendor CenterMS-14 Avisos y ayudaMS-02 ProductoSellerBFF1. Pide avisar que la carga terminó con erroresPOST /internal/notifications/messages2. Abre su carga desde el aviso3. Lista sus cargas recientes con su estadoGET /api/v2/product-imports4. Ve el resultado por renglón y por varianteGET /api/v2/product-imports/{id}5. Baja el mismo archivo con la columna de resultadoGET /api/v2/product-imports/{id}/reportSellerBFF
Reporte por renglón al terminar

4. Si algo sale mal

  • La estructura del archivo no coincide con la plantilla. La subida responde 422 con las columnas que sobran o faltan y no se procesa ningún renglón; el seller ve «esta estructura no coincide» y baja la plantilla vigente.
  • Un renglón trae un color fuera de la lista, letras en un número o un EAN repetido. Ese renglón queda «por corregir» con la columna y el motivo (por ejemplo, «EAN duplicado»); los demás siguen. El seller corrige en el mismo archivo y vuelve a subir sólo lo que falló.
  • MS-06 no responde o tarda en evaluar. La carga se queda en «evaluando» y MS-02 reintenta por bloque; ningún renglón se crea sin evaluación. Si pasa de dos horas, la carga termina con error de dependencia y el seller recibe el aviso para subirla de nuevo; el archivo original queda guardado.
  • La plantilla cambió entre que la bajó y la subió. Los renglones a los que les falta algo que pide la versión vigente salen con TEMPLATE_VERSION_OUTDATED y el detalle de qué falta; si sólo cambió lo opcional, se procesan.
  • El archivo pasa de 20,000 renglones o trae más de cinco plantillas. Se rechaza completo con el motivo, nunca se trunca; el seller lo parte en archivos más chicos.

5. APIs

Las que construye esta épica (8)

GET /bff/v1/bulk-loads/start · Pantalla de carga masiva
CampoValor
APIAPI-BFF-203 · BFF del portal
Para quéJunta la pantalla de inicio de la carga masiva: los perfiles que puede usar, sus categorías habituales ya preseleccionadas (las plantillas en que más ha catalogado, calculadas de sus productos en MS-02 y nombradas con la ruta del árbol de MS-01) y sus cargas recientes con su estado.
En esta épicaPantalla de inicio de la carga, con categorías habituales y cargas recientes
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoLa pantalla de carga masiva en el menú del perfil (BFF)
CabecerasAuthorization, X-Request-Id
Parámetrosbusiness = MKP

Request

null

Response · 200

{
  "success": true,
  "data": {
    "business": "MKP",
    "profiles": [
      {
        "profile": "PROPOSALS",
        "maxRows": 20000,
        "maxTemplates": 5
      }
    ],
    "usualTemplates": [
      {
        "templateId": "EU4-0711",
        "path": "Salud > Farmacia > Analgésicos",
        "products": 214,
        "preselected": true
      },
      {
        "templateId": "EU4-0412",
        "path": "Tecnología > Energía > Baterías portátiles",
        "products": 37,
        "preselected": true
      }
    ],
    "recentLoads": [
      {
        "importId": "imp-20261018-0042",
        "status": "DONE_WITH_ERRORS",
        "createdAt": "2026-10-18T16:02:11Z",
        "summary": {
          "rows": 12000,
          "created": 11841,
          "toCorrect": 101,
          "alreadyExists": 49,
          "blocked": 7
        }
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERROREl perfil no tiene la pantalla de carga masiva o el negocio no es suyo
503DEPENDENCY_UNAVAILABLEMS-02 no responde
GET /api/v2/product-imports/profiles · Perfiles de carga masiva de producto
CampoValor
APIAPI-02-044 · MS-02 Producto
Para quéLista los perfiles de carga que puede usar quien llama: propuestas por plantilla y negocio, placeholders de pre-compra y los seis de paridad con P360 para usuarios internos, cada uno con sus límites y el permiso que pide.
En esta épicaPerfiles de carga que puede usar quien llama
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoENT-L; cada perfil dice qué permiso pide para cargar
CabecerasAuthorization, X-Request-Id
Parámetrosbusiness = MKP

Request

null

Response · 200

{
  "success": true,
  "data": {
    "items": [
      {
        "profile": "PROPOSALS",
        "name": "Propuestas por plantilla y negocio",
        "for": [
          "PROVEEDOR",
          "SELLER",
          "INTERNO"
        ],
        "formats": [
          "XLSX",
          "CSV"
        ],
        "maxRows": 20000,
        "maxTemplates": 5,
        "permission": "ENT-E"
      },
      {
        "profile": "PLACEHOLDERS",
        "name": "Placeholders de pre-compra",
        "for": [
          "PROVEEDOR",
          "INTERNO"
        ],
        "formats": [
          "XLSX"
        ],
        "maxRows": 20000,
        "maxTemplates": 5,
        "permission": "ENT-E"
      },
      {
        "profile": "PRODUCT_VALUES_V1",
        "name": "Valores de producto (paridad con P360)",
        "for": [
          "INTERNO"
        ],
        "formats": [
          "CSV",
          "XLSX"
        ],
        "maxRows": 100000,
        "maxTemplates": null,
        "permission": "VAL-E"
      }
    ],
    "page": 1,
    "size": 50,
    "total": 8
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORQuien llama no tiene lectura de productos
GET /api/v2/product-imports/profiles/{p}/template · Bajar la plantilla de carga
CampoValor
APIAPI-02-045 · MS-02 Producto
Para quéGenera la plantilla descargable de una a cinco plantillas para un negocio con la vista efectiva vigente de MS-01: en blanco si se pidió por categoría, o prellenada con los productos buscados por SKU o EAN para corregirlos.
En esta épicaBajar la plantilla en blanco o prellenada, con colores por negocio
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoENT-L; el proveedor o seller sólo para sus negocios y, al prellenar, sólo con sus productos
CabecerasAuthorization, X-Request-Id
Parámetrosp = PROPOSALS, business = MKP, templateIds = EU4-0412,EU4-0533, prefillSkus = None, prefillEans = None, format = XLSX
También la usanFT-CAT-03, FT-FLU-06, FT-PRD-05

Request

null

Response · 200

"Archivo XLSX: una hoja por plantilla con su versión en el encabezado; cada columna en rojo (obligatorio), amarillo (recomendado) o blanco (opcional) para el negocio; listas cerradas por código; si se pidió por SKU o EAN, un renglón por producto con sus datos. Una hoja «Léeme» explica por qué baja vacía cuando se pidió por categoría."

Errores

HTTPCódigoCuándo
404NOT_FOUNDEl perfil o una plantilla no existen, o la plantilla no es una hoja del árbol
422VALIDATION_ERRORMás de cinco plantillas, o más de 500 productos para prellenar
403AUTHORIZATION_ERROREl negocio no es del proveedor o seller
POST /api/v2/product-imports · Subir una carga masiva de producto
CampoValor
APIAPI-02-046 · MS-02 Producto
Para quéRecibe un archivo, los renglones de la plantilla en línea o un lote de la API de terceros (source.type = FILE, ROWS o PARTNER_BATCH); responde al momento con el ID de carga y valida en segundo plano, sin escribir productos, la estructura, los tipos, las listas, los obligatorios del negocio y la evaluación de MS-06 de cada renglón (API-06-002).
En esta épicaSubir la carga y recibir el ID al momento
Quién la llamaEntrada Única · Vendor Center (por el BFF), Gateway de terceros /partner/v1
PermisoEl del perfil: ENT-E para propuestas y placeholders (el proveedor o seller sólo en sus negocios); ENT-E y VAL-E para los perfiles de paridad
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enproduct_jobs
También la usanFT-CAT-06, FT-FLU-05, FT-FLU-06, FT-INT-07, FT-PRD-05, FT-PRD-09, FT-PRD-10, FT-RAC-01

Request

{
  "profile": "PROPOSALS",
  "business": "MKP",
  "source": {
    "type": "FILE",
    "fileName": "carga-octubre.xlsx",
    "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "sha256": "9f2c41d0…",
    "content": "(el archivo va en la misma petición, multipart/form-data, hasta 50 MB)"
  },
  "applyWhenValidated": false,
  "submitWhenComplete": true,
  "notify": [
    "SCREEN",
    "EMAIL"
  ]
}

Response · 202

{
  "success": true,
  "data": {
    "importId": "imp-20261018-0042",
    "jobId": "job-7c31e0",
    "status": "VALIDATING",
    "received": {
      "rows": 12000,
      "templates": 3
    },
    "links": {
      "self": "/api/v2/product-imports/imp-20261018-0042",
      "apply": "/api/v2/product-imports/imp-20261018-0042/apply",
      "report": "/api/v2/product-imports/imp-20261018-0042/report"
    }
  }
}

Errores

HTTPCódigoCuándo
400VALIDATION_ERROREl archivo no se puede leer o no corresponde al perfil
422VALIDATION_ERRORLa estructura no coincide (columnas ajenas UNKNOWN_COLUMN, columnas que faltan o encabezado de otra plantilla): se rechaza completo sin leer renglones
413LIMIT_EXCEEDEDMás de 20,000 renglones, más de cinco plantillas, más de 50 MB o, en la plantilla en línea, más de 500 renglones: se rechaza completo, nunca se trunca
403AUTHORIZATION_ERROREl negocio no es del proveedor o seller, o el perfil pide un permiso que no tiene
429RATE_LIMITEDYa tiene dos cargas en proceso
409IDEMPOTENCY_MISMATCHSe repite la llave de idempotencia con otro archivo
POST /api/v2/product-imports/{id}/apply · Confirmar una carga masiva
CampoValor
APIAPI-02-047 · MS-02 Producto
Para quéConfirma una carga ya validada y aplica, renglón por renglón, sólo los válidos con la misma alta completa que API-02-006 sin productId: cada propuesta nueva nace en Borrador con su origen (BULK, o PARTNER_API si el lote vino del gateway), su plantilla y su evaluación de MS-06, y si trae completos los obligatorios de su negocio se envía en la misma confirmación. Los renglones con ID de producto existente se aplican como cambio (vacío = no cambiar, __NULL__ = vaciar).
En esta épicaConfirmar y crear los renglones válidos
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoQuien subió la carga
CabecerasAuthorization, X-Request-Id, Idempotency-Key, If-Match
Parámetrosid = imp-20261018-0042
Escribe enproducts, identifier_registry, tasks, product_versions, product_jobs, product_receipts, product_outbox
Publicacatalog.product.changed/PRODUCT_CREATED, catalog.product.changed/PRODUCT_UPDATED, catalog.product.changed/STATUS_CHANGED, catalog.product.changed/TASK_CHANGED
También la usanFT-CAT-06, FT-FLU-05, FT-FLU-06, FT-INT-07, FT-PRD-05, FT-PRD-09, FT-RAC-01

Request

{
  "apply": "ALL_VALID",
  "excludeRows": [
    118,
    4021
  ],
  "submitWhenComplete": true
}

Response · 202

{
  "success": true,
  "data": {
    "importId": "imp-20261018-0042",
    "requestId": "req-91d2a4",
    "status": "APPLYING",
    "toApply": 11841,
    "receiptUrl": "/api/v2/product-receipts/req-91d2a4",
    "links": {
      "self": "/api/v2/product-imports/imp-20261018-0042"
    }
  }
}

Errores

HTTPCódigoCuándo
409NOT_EDITABLE_IN_STATUSLa carga todavía se está validando o ya se aplicó
409VERSION_CONFLICTEl resultado de la validación cambió desde que se leyó
409PLAN_EXPIREDPasaron más de 24 horas desde la validación: hay que validar otra vez
409IDEMPOTENCY_MISMATCHSe repite la llave con otra selección de renglones
GET /api/v2/product-imports/{id} · Estado y resultado de una carga
CampoValor
APIAPI-02-048 · MS-02 Producto
Para quéDice en qué va una carga (validando, validada, aplicando, terminada o terminada con errores) y qué pasó con cada renglón y cada variante: válido, por corregir con columna y motivo, ya existe con su acción o bloqueado; al aplicar, el ID de cada propuesta creada.
En esta épicaEstatus por archivo, por renglón y por variante
Quién la llamaEntrada Única · Vendor Center (por el BFF), Gateway de terceros /partner/v1
PermisoQuien subió la carga; Gobierno de Producto con lectura
CabecerasAuthorization, X-Request-Id
Parámetrosid = imp-20261018-0042, result = NOT_VALID, page = 1, size = 200
También la usanFT-FLU-06, FT-PRD-10, FT-RAC-01

Request

null

Response · 200

{
  "success": true,
  "data": {
    "importId": "imp-20261018-0042",
    "profile": "PROPOSALS",
    "business": "MKP",
    "origin": "BULK",
    "channel": "FILE",
    "status": "VALIDATED",
    "createdAt": "2026-10-18T16:02:11Z",
    "validatedAt": "2026-10-18T16:09:40Z",
    "summary": {
      "rows": 12000,
      "valid": 11843,
      "toCorrect": 101,
      "alreadyExists": 49,
      "blocked": 7,
      "created": 0
    },
    "items": [
      {
        "row": 7,
        "externalRef": "SKU-PROV-00071",
        "result": "CORRECTION_REQUIRED",
        "errors": [
          {
            "column": "COLOR",
            "attribute": "COLOR",
            "variantRow": 2,
            "code": "VALUE_NOT_IN_LIST",
            "value": "Rojo vino",
            "message": "«Rojo vino» no está en la lista; usa el código"
          }
        ]
      },
      {
        "row": 12,
        "externalRef": "SKU-PROV-00112",
        "result": "ALREADY_EXISTS",
        "match": {
          "matchType": "EAN",
          "catalog": "MARKETPLACE",
          "sku": "1000004812"
        },
        "allowedAction": "MULTI_OFFER",
        "message": "Crea una multioferta: el producto ya existe en Marketplace"
      },
      {
        "row": 15,
        "externalRef": "SKU-PROV-00115",
        "result": "REJECTED",
        "errors": [
          {
            "column": "MARCA",
            "code": "BRAND_BLOCKED",
            "message": "La marca no se puede catalogar en Marketplace"
          }
        ]
      },
      {
        "row": 31,
        "externalRef": "SKU-PROV-00131",
        "result": "CORRECTION_REQUIRED",
        "errors": [
          {
            "column": "EAN",
            "code": "EAN_DUPLICATED",
            "value": "7501234567923",
            "message": "EAN duplicado: lo usa otro SKU del mismo negocio"
          }
        ]
      }
    ],
    "page": 1,
    "size": 200,
    "total": 157
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDLa carga no existe o no es de quien llama
GET /api/v2/product-imports · Mis cargas masivas
CampoValor
APIAPI-02-204 · MS-02 Producto
Para quéLista las cargas de quien llama (o de su proveedor o seller) con su estado y su resumen, para la pantalla de carga y el seguimiento.
En esta épicaMis cargas con su estado
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoQuien subió las cargas; el proveedor o seller ve las de su cuenta; Gobierno de Producto con lectura
CabecerasAuthorization, X-Request-Id
Parámetrosstatus = DONE_WITH_ERRORS, business = MKP, from = 2026-10-01, page = 1, size = 20
También la usanFT-FLU-06

Request

null

Response · 200

{
  "success": true,
  "data": {
    "items": [
      {
        "importId": "imp-20261018-0042",
        "profile": "PROPOSALS",
        "business": "MKP",
        "channel": "FILE",
        "status": "DONE_WITH_ERRORS",
        "createdAt": "2026-10-18T16:02:11Z",
        "finishedAt": "2026-10-18T16:21:05Z",
        "summary": {
          "rows": 12000,
          "created": 11841,
          "toCorrect": 101,
          "alreadyExists": 49,
          "blocked": 7
        }
      }
    ],
    "page": 1,
    "size": 20,
    "total": 1
  }
}

Errores

HTTPCódigoCuándo
400VALIDATION_ERRORUn filtro trae un valor que no existe
GET /api/v2/product-imports/{id}/report · Reporte por renglón de una carga
CampoValor
APIAPI-02-205 · MS-02 Producto
Para quéDevuelve el mismo archivo que se subió con tres columnas finales por renglón: resultado (creado, por corregir, ya existe o bloqueado), ID de la propuesta creada y detalle con la columna y el motivo; sale siempre, haya o no errores.
En esta épicaReporte: el mismo archivo con una columna final de resultado
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoQuien subió la carga
CabecerasAuthorization, X-Request-Id
Parámetrosid = imp-20261018-0042, format = XLSX
También la usanFT-FLU-05

Request

null

Response · 200

"Archivo XLSX o CSV: el archivo original con las columnas RESULTADO, ID_PROPUESTA y DETALLE al final de cada renglón; por ejemplo «CORRECTION_REQUIRED | | COLOR: «Rojo vino» no está en la lista»."

Errores

HTTPCódigoCuándo
404NOT_FOUNDLa carga no existe o no es de quien llama
409NOT_EDITABLE_IN_STATUSLa carga todavía se está validando: el reporte sale al terminar

Las que usa y construye otra épica (7)

Su request y su response están en la página de la épica que la construye.

APIMétodo y rutaPara qué, aquíLa construye
API-02-001POST /api/v2/products/searchBuscar por SKU o EAN los productos a prellenarFT-PRD-01 · Modelo canónico de producto
API-01-028GET /api/v2/taxonomies/PRODUCT/nodes/{id}/effectiveVista efectiva de cada plantilla por negocioFT-PLT-06 · Configuración de atributos por plantilla y por negocio…
API-06-002POST /api/v2/evaluations/batchesEvaluar los renglones por bloque con las reglas del alta individualFT-FLU-05 · Reglas de negocio en la carga masiva
API-06-003GET /api/v2/evaluations/batches/{batchId}Leer la decisión de cada renglónFT-FLU-05 · Reglas de negocio en la carga masiva
API-02-006POST /api/v2/products/guided/plansLa misma alta completa que corre por cada renglón válido, con origen BULKFT-PRD-07 · Captura guiada por pasos con los mínimos primero
API-14-005POST /internal/notifications/messagesAvisar al seller que su carga terminóFT-RAC-05 · Estatus del producto y motivos visibles para seller y…
API-BFF-104POST /bff/v1/catalog/template-section-checksRevisar que cada plantilla elegida esté ligada a la sección y al negocio del proveedorFT-PLT-10 · Fachada v1 compatible con P360 para Entrada Única y Foro

6. Eventos

Publica

EventoCuándoQuién lo consume
catalog.product.changed/PRODUCT_CREATEDSe crea cada renglón válidoFT-ARQ-01
catalog.product.changed/PRODUCT_UPDATEDSe aplica un renglón de cambio de un producto que ya existíaFT-ACT-05, FT-ARQ-02, FT-IA-01, FT-PLT-07, FT-PRD-05, FT-RAC-06
catalog.product.changed/STATUS_CHANGEDUn renglón completo se envía a revisiónFT-ACT-05, FT-ARQ-02, FT-CAT-05, FT-FLU-01, FT-IA-04, FT-PRD-02, FT-PRD-04, FT-PRD-06, FT-PRD-10, FT-RAC-03, FT-RAC-05, FT-RAC-06
catalog.product.changed/TASK_CHANGEDSe abre la Validación automática o el visto bueno de ComprasFT-ACT-05, FT-ACT-06, FT-ARQ-02, FT-CAT-06, FT-FLU-01, FT-IA-06, FT-PRD-02, FT-PRD-05, FT-PRD-06, FT-PRD-07, FT-PRD-08, FT-RAC-02, FT-RAC-03, FT-RAC-04, FT-RAC-05, FT-RAC-06

Consume

EventoPara quéQuién lo publica
catalog.validation.result/EVALUATION_DONEMS-02 sigue con la carga cuando MS-06 terminó de evaluar un bloque de renglonesFT-FLU-03, FT-FLU-05, FT-REF-03

7. Datos

Cada colección tiene un solo dueño, el único que escribe en ella.

ColecciónDueñoQué guardaEsta épica
product_jobsMS-02Trabajos asíncronos: cargas masivas de productos, edición masiva y publicación.escribe
productsMS-02La familia del producto con sus variantes, valores, imágenes (URL), clasificaciones, estado, tareas abiertas y rechazos.escribe
identifier_registryMS-02Unicidad de SKU y de EAN por negocio.escribe
tasksMS-02Todo el trabajo asignado: visto bueno, corrección, Gobierno de Datos, foto, secciones, QA, revisión del cambio y repoblamiento.escribe
product_versionsMS-02Foto numerada del producto en cada versión.escribe
product_receiptsMS-02El recibo de cada escritura confirmada en el producto (antes operation_receipts).escribe
product_outboxMS-02Los cambios del producto que esperan salir como evento (antes outbox).escribe
template_viewsMS-01La vista efectiva ya resuelta por plantilla y negocio: qué atributos pide y cuáles son obligatorios.lee
governance_rulesMS-01Reglas de captura y clasificación: marcas por plantilla, grupo de artículo a plantilla, alcance del proveedor y lista negra de Marketplace.lee
validation_resultsMS-06El resultado de cada evaluación: lista negra, coincidencias con su confianza y score.lee

8. Historias que cubre

HistoriaPrioridadCómo la cubre
FT-FLU-04·H1 · Descargar y subir la plantilla de una categoríaP1pasos 1, 2, 4, 5, 6; flujo «Plantilla prellenada para corregir»; API-02-045, API-02-046
FT-FLU-04·H2 · Recepción asíncronaP1pasos 6, 7, 14; flujo «Reporte por renglón al terminar»; API-02-048, API-02-204, API-14-005
FT-FLU-04·H3 · Validación y reporte por renglónP1pasos 8, 9, 10; flujo «Reporte por renglón al terminar»; API-02-205
FT-FLU-04·H4 · Plantilla por negocio con coloresP2pasos 4, 5; API-02-045
FT-FLU-04·H5 · Mercaderías por la misma cargaP3flujo «Mercaderías por la misma carga»
FT-FLU-04·H6 · Mis categoríasP2pasos 2; API-BFF-203
FT-FLU-04·H7 · Plantilla prellenada si busco por códigoP1flujo «Plantilla prellenada para corregir»
FT-FLU-04·H8 · Varias plantillas en un archivoP2pasos 3, 4, 6; API-02-044, API-BFF-104

9. Decisiones de esta épica

Las tomó el TL como arquitecto; quedan como [Propuesta] hasta que el equipo de la épica las revise.

  • D-FLU-04-1. La carga masiva es un trabajo de MS-02 (product_jobs) que corre en su despliegue de trabajo, el mismo artefacto del módulo, como hoy product-massive en Entrada Única. El archivo original y el reporte se guardan en el almacén de archivos; la carga sólo guarda su referencia. Por qué: Las cargas pesadas no deben competir con las pantallas, y separar el despliegue no agrega una pieza que operar (decisión 6 de la validación con código). Se apoya en ADR-12, PD-05.
  • D-FLU-04-2. Dos pasos, como hoy en Entrada Única (validar y procesar): subir valida todo sin crear nada y da el ID al momento; al terminar, el seller ve el resultado y confirma los válidos. Con applyWhenValidated los válidos se crean solos al terminar la validación: lo usan el gateway para sus lotes y el seller que lo pida. Por qué: Medido en el código del front (18-oct): hoy son validate-proposal-file y process-proposal-file. Mantener los dos pasos no cambia el hábito del seller y sigue la regla de escribir en dos pasos. Se apoya en RN-MAS-02, RN-MAS-01, DEC-54.
  • D-FLU-04-3. Renglón por renglón: un renglón malo no tumba la carga y los válidos se crean. El todo o nada se queda para la carga de configuración del catálogo. Por qué: Es lo que pidieron los talleres (S10: se crea lo que no tiene coincidencia) y lo que hace hoy Entrada Única; resuelve la duda de RQ-14. Se apoya en RN-MAS-04, DEC-58, RF-MAS-08.
  • D-FLU-04-4. Un archivo es de un solo negocio. Quien vende en varios negocios baja y sube un archivo por negocio, cada uno con sus colores: rojo obligatorio, amarillo recomendado y blanco opcional. Por qué: El encabezado no admite obligatoriedad por negocio; separar por negocio resuelve PEN-56 sin plantillas combinadas y es la misma regla de un negocio por lote de la API de terceros. Se apoya en PEN-55, PEN-56, DUD-32, RF-MAS-09, RF-MAS-10.
  • D-FLU-04-5. Límites de arranque: hasta 20,000 renglones, cinco plantillas y 50 MB por archivo, y dos cargas en proceso por cuenta; lo que pasa el límite se rechaza completo con el motivo, nunca se trunca. La plantilla lleva su versión: si la vigente pide algo que el archivo no trae, el renglón sale con TEMPLATE_VERSION_OUTDATED. Por qué: Cubre los 10,000 a 20,000 productos por archivo de los talleres y las cinco plantillas por archivo de P-07; los valores se ajustan con la prueba de carga. Se apoya en RF-MAS-05, P-07, RN-PLA-08.
  • D-FLU-04-6. Prellenado sólo cuando se busca por SKU o EAN (hasta 500 productos por descarga); pedida por categoría, la plantilla baja vacía y lo explica. Un renglón con ID de producto existente es un cambio: vacío = no cambiar y __NULL__ = vaciar, con la misma validación y el mismo motor que un cambio en pantalla; si el producto ya está aprobado, abre la revisión del cambio. Por qué: Cubre H7 y la modificación masiva que hoy hace Entrada Única (RQ-15) sin un flujo aparte. Se apoya en RF-MAS-01, RF-MAT-21, FT-PRD-05.
  • D-FLU-04-7. Mercaderías y Suburbia usan la misma carga. Cada renglón válido sigue la ruta de su negocio: en Mercaderías se envía al visto bueno de Compras como cualquier propuesta, y las reglas de datos (EAN usado por otro SKU) las corre MS-06 con la evaluación del bloque. Por qué: El SKU se crea con la misma lógica por cualquier canal y Compras no pierde su revisión por el canal de entrada; resuelve la duda de H5. Se apoya en DEC-59, RN-ALT-12, RN-ALT-05.
  • D-FLU-04-8. El reporte sale siempre al final: el mismo archivo con tres columnas de resultado (resultado, ID de la propuesta y detalle) y el resultado por renglón en la pantalla. El aviso de fin lo manda MS-14 por pantalla y correo. Sin SLA hasta medir; la referencia es de 5 a 10 minutos. Por qué: «La clave es el reporte»: siempre, por renglón y sin mandar al seller a otra pantalla; el formato elegido resuelve PEN-59. Se apoya en RN-MAS-04, PEN-59, PEN-12.
  • D-FLU-04-9. «Mis categorías» no se guardan aparte: el BFF las calcula de los productos del proveedor (cuenta por plantilla en MS-02) y las nombra con la ruta del árbol de MS-01. Por qué: Un dato que se deduce no se duplica y siempre refleja lo que el proveedor sí catalogó (H6). Se apoya en ADR-12.

Qué falta decidir

IDQué falta
PD-02En R2 la carga del portal pasa al PIM con las reglas de hoy; las reglas TO-BE de Marketplace (evaluación de MS-06 por renglón) dependen de que el alta de sellers suba antes de R4.

También siguen abiertos: PEN-55, Marketplace con Gobierno de Producto confirma cómo se identifica el negocio de un proveedor híbrido (aquí, un archivo por negocio); PEN-59, Ratificar el formato del reporte (aquí, el mismo archivo con columnas de resultado); PEN-12, Confirmar canal y frecuencia del aviso de fin de carga.

Fuentes

  1. [D] trazabilidad/features/FT-FLU-04-carga-masiva-productos-por-archivo.md: la ficha de la épica, con sus historias, reglas y bloqueos.
  2. [D] ADR-12 · Un solo sistema: backend compartido y una sola base (sección 3.4).
  3. [D] docs/arquitectura/por-epica/base/: piezas, colecciones, eventos y el hilo de punta a punta.
  4. [D] docs/arquitectura/omega-a-pim-headless/contratos-api.md: convenciones y endpoints de partida.
  5. [D] docs/arquitectura/maquina-de-estados-to-be/propuesta-maquina-de-estados.md §7: estados, tareas y canales.
  6. [I] Las decisiones de la sección 9 son del TL sobre esas fuentes.