← Arquitectura por épica

FT-ACT-02 · Registro, congelado y publicación de URLs de activos

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-ACT-02: 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-ACT-02.json, generada con generar.py; la ficha de la épica es trazabilidad/features/FT-ACT-02-registro-congelado-publicacion-urls.md.

En 30 segundos

Cuando un producto ya tiene SKU y la foto la pone el proveedor, éste sube sus imágenes en el portal. Esta épica guarda cada archivo una sola vez en Activos digitales, lo valida, lo nombra con el SKU, hace la copia congelada que se publica y le pasa a Producto la URL congelada de cada variante. Así la tienda sólo recibe imágenes estables y una variante sin principal no frena a su familia.

  • Módulo dueño: MS-11 Activos digitales. También participan: MS-02 Producto, MS-14 Avisos y ayuda.
  • Etapa 6 · Imágenes. Recibe «PE-6 · SKU asignado» y entrega «PE-7 · Imágenes listas».
  • APIs: construye 11 y usa 9 que construyen otras épicas.
  • Eventos: publica 9 y consume 5.

1. Dónde encaja

Recibe

DeQué
PE-6 · SKU asignadoLa familia En enriquecimiento con SKU en cada variante y, si la foto la pone el proveedor y todavía no cumple el mínimo de aprobación, la tarea Carga de imagen abierta.
FT-ACT-01 · Tipos de activo digital y reglas de imágenes por…Los tipos de activo con su ficha, nombre, sufijo y carpeta, y la revisión de cumplimiento por plantilla, negocio y etapa.

Entrega

AQué
PE-7 · Imágenes listasLa tarea Carga de imagen cerrada: las imágenes en MS-11 con URL congelada, ligadas a su variante y posición, y su copia en el producto.
FT-INT-01 · Publicación a e-commerceLa copia de URL congeladas por variante, con «procede» o «no procede», que lee la foto de publicación (API-02-054): sin principal congelada no se publica.
FT-ACT-03 · Imágenes del seller por URL con validación y corrección…El registro, la validación, el congelado al asignar el SKU y los recibos que usa la imagen del seller por URL.
FT-ACT-06 · Recepción del trabajo de Foro y control de edición…La consulta de las imágenes que ya tiene cada variante y el congelado al validar, que usa el cierre de la edición del estudio.
FT-ACT-04 · Variantes a partir de imágenes y herencia de imágenes por…El registro de activos, el congelado y la copia de URL congeladas en el producto, sobre los que se resuelve la herencia por color.
FT-MIG-03 · Migración inicial de productos desde P360La carga de activos migrados (API-11-016): cada URL de trabajo y congelada de P360 queda una vez en MS-11, sin copiar archivos ni cambiar URL.

Tareas que abre o cierra: Carga de imagen.

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

Sistemas externos

Nuevo PIM · un solo sistema

Pantallas y sistemas

Personas

Pedir permiso para subir un archivo
Avisar que terminó la carga
y 5 más

Qué puede hacer quien llama

Sube el archivo directo con la URL fi…

Valida la ficha, nombra con el SKU y…
Copia de trabajo a congelados con el…
y 1 más

ASSET_FROZEN
ASSET_REJECTED
y 1 más

ASSET_FROZEN

Galería de un producto
¿El producto cumple sus imágenes?
y 1 más

Pedir una acción del flujo
Confirmar un plan de Producto

TASK_CHANGED
MEDIA_CHANGED
y 1 más

SKU_ASSIGNED

ASSET_REJECTED
ASSET_JOB_FINISHED

Manda el motivo y la imagen al provee…

Proveedor

QA y Category

Repoblamiento

Estudio fotográfico

Entrada Única · Vendor Center

BFF del portal

★ MS-11 Activos digitales

MS-02 Producto

MS-14 Avisos y ayuda

Base pim

Eventos

Archivos e imágenes

Servicio de correo

Contexto de FT-ACT-02

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.

Base·pimEventosArchivosMS-02 ProductoMS-11 Activos digitalesEntrada Única · Vendor CenterBase·pimEventosArchivosMS-02 ProductoMS-11 Activos digitalesEntrada Única · Vendor CenterProveedorBFF1. Abre su tarea Carga de imagen y elige sus fotos2. Pide permiso para subir cada archivoPOST /api/v2/assets/uploads3. Revisa que el proveedor pueda cambiar las imágenesGET /api/v2/workflow/capabilities?productIds=4. Sube el archivo directo con la URL firmada5. Avisa que terminó la cargaPOST /api/v2/assets/{assetId}/complete6. Valida la ficha, nombra con el SKU y congela7. Avisa el activo validado y congeladoASSET_FROZEN8. Entrega el activo congeladoASSET_FROZEN9. Lee la galería congelada de cada varianteGET /api/v2/assets?productId=&variantId=10. Copia las URL congeladas y marca procede por variante11. Pide el plan para enviar sus imágenesPOST /api/v2/workflow/actions/plans12. Revisa el mínimo de su plantilla y negocioGET /api/v2/assets/compliance?productId=&stage=13. Confirma el envío de las imágenesPOST /api/v2/product-plans/{planId}/apply14. Cierra Carga de imagen y sigue a calidadTASK_CHANGEDProveedorBFF
Flujo principal de FT-ACT-02
Los pasos en texto
PasoDeAQué haceAPI o evento
1ProveedorEntrada Única · Vendor CenterAbre su tarea Carga de imagen y elige sus fotos—
2Entrada Única · Vendor CenterMS-11 Activos digitales (por el BFF)Pide permiso para subir cada archivoAPI-11-004
3MS-11 Activos digitalesMS-02 ProductoRevisa que el proveedor pueda cambiar las imágenesAPI-02-027
4Entrada Única · Vendor CenterArchivos e imágenes (almacén y CDN)Sube el archivo directo con la URL firmada—
5Entrada Única · Vendor CenterMS-11 Activos digitales (por el BFF)Avisa que terminó la cargaAPI-11-005
6MS-11 Activos digitalesArchivos e imágenes (almacén y CDN)Valida la ficha, nombra con el SKU y congela—
7MS-11 Activos digitalesEventosAvisa el activo validado y congeladocatalog.asset.changed/ASSET_FROZEN
8EventosMS-02 ProductoEntrega el activo congeladocatalog.asset.changed/ASSET_FROZEN
9MS-02 ProductoMS-11 Activos digitalesLee la galería congelada de cada varianteAPI-11-007
10MS-02 ProductoBase pimCopia las URL congeladas y marca procede por variante—
11Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Pide el plan para enviar sus imágenesAPI-02-028
12MS-02 ProductoMS-11 Activos digitalesRevisa el mínimo de su plantilla y negocioAPI-11-014
13Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Confirma el envío de las imágenesAPI-02-057
14MS-02 ProductoEventosCierra Carga de imagen y sigue a calidadcatalog.product.changed/TASK_CHANGED

3.1 Congelado al asignar el SKU (la tubería de la imagen)

MS-02 ProductoArchivosMS-11 Activos digitalesEventosMS-02 ProductoArchivosMS-11 Activos digitalesEventos1. Entrega el SKU asignado de cada varianteSKU_ASSIGNED2. Copia de trabajo a congelados con el nombre final3. Avisa cada activo congeladoASSET_FROZEN4. Entrega los activos congeladosASSET_FROZEN5. Lee la galería congelada completaGET /api/v2/assets?productId=&variantId=6. Avisa que cambiaron las imágenes del productoMEDIA_CHANGED7. Tras corregir un SKU, pide volver a congelarPOST /api/v2/assets/freeze
Congelado al asignar el SKU (la tubería de la imagen)

3.2 Rechazar o cambiar imágenes de un producto ya publicado

MS-02 ProductoServicio de correoMS-14 Avisos y ayudaEventosMS-11 Activos digitalesEntrada Única · Vendor CenterMS-02 ProductoServicio de correoMS-14 Avisos y ayudaEventosMS-11 Activos digitalesEntrada Única · Vendor CenterQA y CategoryBFFRepoblamiento1. Rechaza el segundo detalle por logo visible2. Rechaza sólo esa imagen con su motivoPOST /api/v2/assets/{assetId}/rejections3. Avisa la imagen rechazadaASSET_REJECTED4. Entrega el rechazo para avisar al proveedorASSET_REJECTED5. Manda el motivo y la imagen al proveedor6. Agrega un detalle a un producto aprobado7. Pide el plan de la galería nuevaPOST /api/v2/assets/placements/plans8. Confirma la galería nuevaPOST /api/v2/asset-plans/{planId}/apply9. Entrega la imagen nueva ya congeladaASSET_FROZEN10. Lee la galería congeladaGET /api/v2/assets?productId=&variantId=11. Pide republicar sus canales sin regresar a capturaPUBLICATION_REQUESTEDQA y CategoryBFFRepoblamiento
Rechazar o cambiar imágenes de un producto ya publicado

3.3 Carga masiva de imágenes

MS-14 Avisos y ayudaEventosArchivosMS-11 Activos digitalesEntrada Única · Vendor CenterMS-14 Avisos y ayudaEventosArchivosMS-11 Activos digitalesEntrada Única · Vendor CenterEstudio fotográficoBFF1. Elige la carpeta de fotos y su archivo de SKU2. Lanza la carga masiva con la herencia prendidaPOST /api/v2/asset-jobs3. Lee cada foto y la liga por su nombre4. Avisa cada foto congeladaASSET_FROZEN5. Avisa que terminó la cargaASSET_JOB_FINISHED6. Entrega el fin de la carga para avisarASSET_JOB_FINISHED7. Consulta el resultado por archivoGET /api/v2/asset-jobs/{jobId}Estudio fotográficoBFF
Carga masiva de imágenes

4. Si algo sale mal

  • Un archivo no cumple la ficha de su tipo. MS-11 lo rechaza con el motivo de hoy («Error en proporción», «DPI insuficiente», «Imagen corrupta o formato no correcto») y publica ASSET_REJECTED. El proveedor lo ve en el recibo y en su campana (MS-14); la tarea sigue abierta.
  • El proveedor envía sin el mínimo de su plantilla. El plan de MS-02 responde bloqueado con lo que falta por variante, que sale de API-11-014; la tarea Carga de imagen sigue abierta y nada se escribe.
  • El producto entra al estudio mientras el proveedor sube fotos. MS-11 responde 423 LOCKED porque el motor dice que sólo el estudio cambia las imágenes; el proveedor ve «En proceso Liverpool» y no queda nada a medias.
  • MS-02 no está disponible cuando llega un activo congelado. El evento se vuelve a entregar. MS-02 siempre relee la galería completa (API-11-007), así que no importan el orden ni los repetidos.
  • Una variante sigue sin principal congelada. Esa variante queda «no procede» y no viaja a la tienda; el resto de la familia se publica (FT-INT-01) y el proveedor ve «Sin imagen principal» en el motivo del SKU (FT-RAC-05).

5. APIs

Las que construye esta épica (11)

POST /api/v2/assets/uploads · Pedir permiso para subir un archivo
CampoValor
APIAPI-11-004 · MS-11 Activos digitales
Para quéAntes de subir una foto, video o documento, quien carga dice qué es, de qué producto, variante o color, y cuánto pesa. MS-11 revisa la ficha del tipo, el máximo de la plantilla y que el producto se pueda editar (pregunta al motor de MS-02), y devuelve el identificador del activo y una URL firmada de 15 minutos para subir el archivo directo al almacén. El archivo nunca pasa por el BFF ni por MS-02.
En esta épicaPermiso de carga: revisa la ficha, el máximo y el bloqueo, y da la URL firmada
Quién la llamaBFF del portal, Agente del estudio, Gateway de terceros /partner/v1
PermisoEl proveedor o seller dueño del producto; el estudio mientras la tarea Foro está abierta; Repoblamiento en productos publicados; el agente del estudio con su credencial de equipo
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enassets
También la usanFT-ACT-01, FT-ACT-04, FT-ACT-05, FT-ACT-06, FT-PLT-06, FT-PLT-07, FT-PRD-07, FT-REF-04, FT-USR-01

Request

{
  "productId": "PRD-0004812",
  "scope": "VARIANT",
  "variantId": "VAR-0004812-01",
  "assetType": "DETALLE",
  "position": 3,
  "fileName": "1000004812_2p.jpg",
  "contentType": "image/jpeg",
  "sizeBytes": 734003,
  "origin": "AGENTE",
  "purpose": "PRODUCT",
  "replacesAssetId": null
}

Response · 201

{
  "success": true,
  "data": {
    "assetId": "ast-7c21e6",
    "status": "UPLOAD_PENDING",
    "uploadUrl": "almacen.ejemplo.mx/carga/ast-7c21e6?firma=<firma>&vence=900",
    "uploadMethod": "PUT",
    "uploadHeaders": {
      "Content-Type": "image/jpeg"
    },
    "expiresAt": "2026-10-18T16:15:00Z",
    "expected": {
      "widthPx": 940,
      "heightPx": 1215,
      "dpi": 72,
      "formats": [
        "jpg"
      ],
      "maxBytes": 1048576
    },
    "completeUrl": "/api/v2/assets/ast-7c21e6/complete"
  }
}

Errores

HTTPCódigoCuándo
422VALIDATION_ERROREl archivo declarado pesa más que el máximo de su tipo (por ejemplo, una principal de 1.5 MB contra 1 MB) o su formato no está permitido
422VALIDATION_ERRORLa posición no existe para el tipo (por ejemplo, la 21: hay 20 posiciones, la principal y 19 detalles)
422BUSINESS_ERRORYa se alcanzó el máximo de ese tipo en la plantilla (la sexta foto de detalle con «Mínimo 2 - Máximo 5»), o es un boceto y el producto no es un placeholder
423LOCKEDEl producto está en el estudio (tarea Foro abierta) y quien llama no es del estudio
403AUTHORIZATION_ERRORQuien llama no es dueño del producto ni tiene el permiso de imágenes en su tarea
404NOT_FOUNDEl producto, la variante o el color no existen
POST /api/v2/assets/{assetId}/complete · Avisar que terminó la carga
CampoValor
APIAPI-11-005 · MS-11 Activos digitales
Para quéQuien subió el archivo avisa que ya está en el almacén. MS-11 lo valida contra la ficha técnica (medidas, DPI, peso, formato), lee el sufijo del nombre si viene (3P es el tercer detalle), le quita los metadatos EXIF, lo deja como copia de trabajo y, si el producto ya tiene SKU, lo renombra y lo congela. Responde con un recibo y avisa con eventos.
En esta épicaFin de carga: valida, nombra y, con SKU, congela
Quién la llamaBFF del portal, Agente del estudio, Gateway de terceros /partner/v1
PermisoQuien pidió subir el archivo (el mismo token o la misma credencial de equipo)
CabecerasAuthorization, X-Request-Id, Idempotency-Key
ParámetrosassetId = ast-7c21e6
Escribe enassets, asset_outbox
Publicacatalog.asset.changed/ASSET_UPLOADED, catalog.asset.changed/ASSET_VALIDATED, catalog.asset.changed/ASSET_REJECTED, catalog.asset.changed/ASSET_FROZEN
También la usanFT-ACT-01, FT-ACT-04, FT-ACT-05, FT-FLU-07, FT-PRD-07, FT-PRD-08, FT-REF-04

Request

{
  "sizeBytes": 734003,
  "checksum": "sha256:9b1d2c0e7f"
}

Response · 202

{
  "success": true,
  "data": {
    "requestId": "req-4a7e90",
    "assetId": "ast-7c21e6",
    "status": "ACCEPTED",
    "receiptUrl": "/api/v2/asset-receipts/req-4a7e90"
  }
}

Errores

HTTPCódigoCuándo
422VALIDATION_ERROREl archivo no llegó al almacén o su tamaño o su huella no coinciden con lo declarado
409IDEMPOTENCY_MISMATCHSe repite la llave de idempotencia con otro archivo
404NOT_FOUNDEl activo no existe o su permiso de carga ya venció
GET /api/v2/assets?productId=&variantId= · Galería de un producto
CampoValor
APIAPI-11-007 · MS-11 Activos digitales
Para quéDevuelve los activos de un producto o de una variante, por posición, con su validación, su URL de trabajo y su URL congelada. Con view=effective resuelve la galería de cada variante: lo propio, lo heredado de su color (y de qué color viene) y el video de la familia. Un producto sin imágenes devuelve listas vacías, no un error.
En esta épicaLa galería de cada variante; vacía si no tiene imágenes, no un error
Quién la llamaBFF del portal, MS-02 Producto, MS-12 Estudio fotográfico
PermisoQuien puede leer el producto (ENT-L); los módulos con su cuenta de servicio
CabecerasAuthorization, X-Request-Id
ParámetrosproductId = PRD-0004812, variantId = `, view = effective, include = work,frozen`
También la usanFT-ACT-04, FT-ACT-05

Request

null

Response · 200

{
  "success": true,
  "data": {
    "productId": "PRD-0004812",
    "assetsVersion": 9,
    "family": [
      {
        "assetId": "ast-7c21f0",
        "assetType": "VIDEO",
        "scope": "FAMILY",
        "kind": "FILE",
        "name": "1000004811.mp4",
        "frozenUrl": "cdn.ejemplo.mx/v/1000004811.mp4",
        "status": "FROZEN"
      }
    ],
    "variants": [
      {
        "variantId": "VAR-0004812-01",
        "sku": "1000004812",
        "colorCode": "AZUL",
        "gallery": [
          {
            "position": 1,
            "assetType": "PRINCIPAL",
            "assetId": "ast-7c21e4",
            "scope": "COLOR",
            "inherited": false,
            "name": "1000004812.jpg",
            "workUrl": "cdn.ejemplo.mx/trabajo/ast-7c21e4.jpg",
            "frozenUrl": "cdn.ejemplo.mx/i/1000004812.jpg",
            "status": "FROZEN"
          },
          {
            "position": 2,
            "assetType": "DETALLE",
            "assetId": "ast-7c21e5",
            "scope": "COLOR",
            "inherited": false,
            "name": "1000004812_1p.jpg",
            "workUrl": "cdn.ejemplo.mx/trabajo/ast-7c21e5.jpg",
            "frozenUrl": "cdn.ejemplo.mx/i/1000004812_1p.jpg",
            "status": "FROZEN"
          }
        ]
      },
      {
        "variantId": "VAR-0004812-02",
        "sku": "1000004813",
        "colorCode": "AZUL",
        "gallery": [
          {
            "position": 1,
            "assetType": "PRINCIPAL",
            "assetId": "ast-7c21e4",
            "inherited": true,
            "inheritedFrom": {
              "scope": "COLOR",
              "colorCode": "AZUL"
            },
            "name": "1000004812.jpg",
            "frozenUrl": "cdn.ejemplo.mx/i/1000004812.jpg",
            "status": "FROZEN"
          },
          {
            "position": 2,
            "assetType": "DETALLE",
            "assetId": "ast-7c21e5",
            "inherited": true,
            "inheritedFrom": {
              "scope": "COLOR",
              "colorCode": "AZUL"
            },
            "name": "1000004812_1p.jpg",
            "frozenUrl": "cdn.ejemplo.mx/i/1000004812_1p.jpg",
            "status": "FROZEN"
          }
        ]
      },
      {
        "variantId": "VAR-0004812-04",
        "sku": "1000004815",
        "colorCode": "ROJO",
        "gallery": []
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDEl producto no existe o no es visible para quien llama (un producto sin imágenes no es error)
400VALIDATION_ERRORFalta productId o view trae un valor que no existe
GET /api/v2/assets/{assetId} · Detalle de un activo
CampoValor
APIAPI-11-008 · MS-11 Activos digitales
Para quéDetalle de un activo: a qué producto, variante o color pertenece, su tipo y posición, la original y la corregida o editada, su validación, su rechazo si lo tiene, sus URL y una URL firmada de 10 minutos para previsualizarlo, también si es un documento de respaldo que no se publica.
En esta épicaPrevisualizar una imagen o un documento de respaldo con URL firmada corta
Quién la llamaBFF del portal
PermisoQuien puede leer el producto (ENT-L); los documentos de respaldo, sólo los roles autorizados de su tipo
CabecerasAuthorization, X-Request-Id
ParámetrosassetId = ast-7c21e6
También la usanFT-REF-04

Request

null

Response · 200

{
  "success": true,
  "data": {
    "assetId": "ast-7c21e6",
    "productId": "PRD-0004812",
    "scope": "COLOR",
    "colorCode": "AZUL",
    "assetType": "DETALLE",
    "position": 3,
    "status": "FROZEN",
    "version": 3,
    "origin": "AGENTE",
    "replacesAssetId": null,
    "renditions": {
      "original": {
        "sizeBytes": 734003,
        "widthPx": 940,
        "heightPx": 1215,
        "dpi": 72,
        "format": "jpg"
      },
      "work": {
        "url": "cdn.ejemplo.mx/trabajo/ast-7c21e6.jpg"
      },
      "frozen": {
        "url": "cdn.ejemplo.mx/i/1000004812_2p.jpg",
        "name": "1000004812_2p.jpg",
        "frozenAt": "2026-10-18T16:03:10Z"
      }
    },
    "validation": {
      "result": "PASSED",
      "checks": [
        "MEDIDAS",
        "DPI",
        "PESO",
        "FORMATO"
      ],
      "corrections": [],
      "exifRemoved": true
    },
    "rejection": null,
    "previewUrl": "cdn.ejemplo.mx/vista/ast-7c21e6?firma=<firma>&vence=600"
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDEl activo no existe o no es visible para quien llama
403AUTHORIZATION_ERROREs un documento de respaldo y quien llama no tiene el rol que lo puede ver
POST /api/v2/assets/placements/plans · Acomodar los activos de un producto (vista previa)
CampoValor
APIAPI-11-009 · MS-11 Activos digitales
Para quéPrepara cambios en la galería de un producto: ordenar, mover de posición, heredar por color (total o sólo lo que falta), volver propia una imagen, quitar o marcar que no se publique. Dice cómo queda la galería de cada variante, qué nombres cambian y qué imágenes propias se pisarían; no pisa nada sin overwriteOwn.
En esta épicaOrdenar, quitar o marcar que no se publique una imagen
Quién la llamaBFF del portal
PermisoEl dueño del contenido del producto; el estudio mientras la tarea Foro está abierta; Repoblamiento en productos publicados
CabecerasAuthorization, X-Request-Id, Idempotency-Key, If-Match
También la usanFT-ACT-04, FT-ACT-06

Request

{
  "productId": "PRD-0004812",
  "assetsVersion": 9,
  "overwriteOwn": false,
  "actions": [
    {
      "op": "INHERIT_BY_COLOR",
      "colorCode": "AZUL",
      "fromVariantId": "VAR-0004812-01",
      "mode": "PARTIAL",
      "assetIds": [
        "ast-7c21e4",
        "ast-7c21e5",
        "ast-7c21e6",
        "ast-7c21e7"
      ]
    },
    {
      "op": "REORDER",
      "colorCode": "AZUL",
      "order": [
        "ast-7c21e4",
        "ast-7c21e6",
        "ast-7c21e5",
        "ast-7c21e7"
      ]
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "planId": "pln-c90e12",
    "expiresAt": "2026-10-18T16:40:00Z",
    "preview": [
      {
        "variantId": "VAR-0004812-01",
        "sku": "1000004812",
        "before": 4,
        "after": 4,
        "inherited": 0
      },
      {
        "variantId": "VAR-0004812-02",
        "sku": "1000004813",
        "before": 0,
        "after": 4,
        "inherited": 4
      },
      {
        "variantId": "VAR-0004812-03",
        "sku": "1000004814",
        "before": 1,
        "after": 4,
        "inherited": 3,
        "keptOwn": [
          {
            "assetId": "ast-7c2201",
            "assetType": "PRINCIPAL"
          }
        ]
      }
    ],
    "renames": [
      {
        "assetId": "ast-7c21e6",
        "from": "1000004812_2p.jpg",
        "to": "1000004812_1p.jpg"
      }
    ],
    "conflicts": [
      {
        "variantId": "VAR-0004812-03",
        "assetType": "PRINCIPAL",
        "message": "La talla XG tiene principal propia; se conserva (overwriteOwn=false)"
      }
    ],
    "applyUrl": "/api/v2/asset-plans/pln-c90e12/apply"
  }
}

Errores

HTTPCódigoCuándo
409VERSION_CONFLICTLa galería cambió desde que se leyó
423LOCKEDEl producto está en el estudio y quien llama no es del estudio
422BUSINESS_ERROREl color no existe en el producto o una acción deja a una variante con dos principales
POST /api/v2/assets/freeze · Volver a congelar los activos de un producto
CampoValor
APIAPI-11-010 · MS-11 Activos digitales
Para quéMS-11 congela solo al recibir SKU_ASSIGNED y al validar un activo de un producto que ya tiene SKU. Este comando sirve a MS-02 para pedir un congelado explícito: después de corregir un SKU o en un repoblamiento. Copia la galería válida al almacén de congelados con el nombre final; si se reemplaza una congelada, la URL nueva lleva su versión para que la tienda no muestre la vieja guardada en caché.
En esta épicaVolver a congelar después de corregir un SKU o en un repoblamiento
Quién la llamaMS-02 Producto
PermisoSólo MS-02 (cuenta de servicio)
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enassets, asset_outbox
Publicacatalog.asset.changed/ASSET_FROZEN

Request

{
  "productId": "PRD-0004812",
  "variantIds": [
    "VAR-0004812-01",
    "VAR-0004812-02"
  ],
  "reason": "SKU_CORRECTED"
}

Response · 202

{
  "success": true,
  "data": {
    "requestId": "req-8c51aa",
    "status": "ACCEPTED",
    "receiptUrl": "/api/v2/asset-receipts/req-8c51aa"
  }
}

Errores

HTTPCódigoCuándo
422BUSINESS_ERRORAlguna variante todavía no tiene SKU
404NOT_FOUNDEl producto no tiene activos registrados
POST /api/v2/asset-jobs · Carga masiva de imágenes
CampoValor
APIAPI-11-011 · MS-11 Activos digitales
Para quéCarga muchas imágenes de una vez: un archivo comprimido, una carpeta del almacén con su archivo que liga fotos y SKU, o una lista de URL. Cada archivo se asocia por su nombre (SKU y sufijo) o por su renglón, se valida igual que uno suelto y la herencia por color se puede prender o apagar. Responde 202 con el trabajo.
En esta épicaCarga masiva por archivo comprimido, carpeta o lista de URL
Quién la llamaBFF del portal, MS-02 Producto
PermisoEl proveedor o seller dueño de los productos; el estudio; MS-02 para las URL de una carga masiva de productos
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enasset_jobs
Publicacatalog.asset.changed/ASSET_UPLOADED, catalog.asset.changed/ASSET_VALIDATED, catalog.asset.changed/ASSET_REJECTED, catalog.asset.changed/ASSET_FROZEN
También la usanFT-ACT-03

Request

{
  "source": "BUCKET_FOLDER",
  "fileRef": "cargas/estudio/2026-10-18/lote-07/",
  "manifest": "lote-07.txt",
  "business": "SUB",
  "inheritance": "ON",
  "origin": "FORO"
}

Response · 202

{
  "success": true,
  "data": {
    "jobId": "job-a1b2c3",
    "status": "QUEUED",
    "links": {
      "self": "/api/v2/asset-jobs/job-a1b2c3"
    }
  }
}

Errores

HTTPCódigoCuándo
422VALIDATION_ERROREl archivo comprimido o la carpeta no existen o el archivo que liga fotos y SKU no se puede leer
429RATE_LIMITEDQuien llama ya tiene el máximo de cargas masivas en curso
GET /api/v2/asset-jobs/{jobId} · Avance de una carga masiva de imágenes
CampoValor
APIAPI-11-012 · MS-11 Activos digitales
Para quéDice cómo va una carga masiva y el resultado de cada archivo: congelado, rechazado con su motivo o pendiente, con una liga firmada al reporte en CSV.
En esta épicaAvance y resultado por archivo de una carga masiva
Quién la llamaBFF del portal, MS-02 Producto
PermisoQuien lanzó la carga
CabecerasAuthorization, X-Request-Id
ParámetrosjobId = job-a1b2c3
También la usanFT-ACT-03

Request

null

Response · 200

{
  "success": true,
  "data": {
    "jobId": "job-a1b2c3",
    "status": "DONE_WITH_ERRORS",
    "startedAt": "2026-10-18T16:05:00Z",
    "finishedAt": "2026-10-18T16:09:41Z",
    "totals": {
      "files": 3,
      "frozen": 2,
      "rejected": 1,
      "pending": 0
    },
    "items": [
      {
        "file": "1000004812.jpg",
        "result": "FROZEN",
        "assetId": "ast-7c2310",
        "sku": "1000004812"
      },
      {
        "file": "1000004812_1p.jpg",
        "result": "FROZEN",
        "assetId": "ast-7c2311",
        "sku": "1000004812"
      },
      {
        "file": "1000009999_2p.jpg",
        "result": "REJECTED",
        "reason": {
          "code": "SKU_NO_EXISTE",
          "message": "El SKU del nombre no existe"
        }
      }
    ],
    "reportUrl": "almacen.ejemplo.mx/reportes/job-a1b2c3.csv?firma=<firma>&vence=3600"
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDLa carga no existe o no es de quien llama
GET /api/v2/asset-receipts/{requestId} · Recibo de una operación de Activos
CampoValor
APIAPI-11-013 · MS-11 Activos digitales
Para quéDice si un comando de MS-11 ya terminó y qué pasó con cada activo: validado, corregido, congelado o rechazado con el motivo que ve el proveedor o seller.
En esta épicaRecibo de cada comando de Activos
Quién la llamaBFF del portal, Agente del estudio, Gateway de terceros /partner/v1, MS-02 Producto
PermisoQuien hizo la operación
CabecerasAuthorization, X-Request-Id
ParámetrosrequestId = req-6b0d13
También la usanFT-ACT-03

Request

null

Response · 200

{
  "success": true,
  "data": {
    "requestId": "req-6b0d13",
    "status": "DONE",
    "finishedAt": "2026-10-18T16:02:14Z",
    "items": [
      {
        "assetId": "ast-9e40a2",
        "result": "VALIDATED",
        "corrections": [
          "DPI_A_72",
          "CENTRADO"
        ],
        "frozen": false,
        "reason": null
      },
      {
        "assetId": "ast-9e40a3",
        "result": "REJECTED",
        "frozen": false,
        "reason": {
          "code": "URL_NO_PUBLICA",
          "message": "No se pudo leer la imagen sin credenciales"
        }
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDNo existe el recibo o no es de quien llama
POST /api/v2/assets/{assetId}/rejections · Rechazar una imagen concreta
CampoValor
APIAPI-11-015 · MS-11 Activos digitales
Para quéQA (o quien revisa) rechaza una sola imagen con un motivo del catálogo de su tipo y un comentario. La imagen sale de la galería que se publica, las demás siguen igual, y MS-02 registra el rechazo en el producto para que el proveedor lo vea.
En esta épicaRechazar una imagen concreta con motivo y tipo
Quién la llamaBFF del portal
PermisoQA, Gobierno de Datos o el estudio, según la tarea que tengan abierta
CabecerasAuthorization, X-Request-Id, Idempotency-Key, If-Match
ParámetrosassetId = ast-7c21e5
Escribe enassets, asset_outbox
Publicacatalog.asset.changed/ASSET_REJECTED

Request

{
  "version": 3,
  "reason": {
    "code": "LOGO_VISIBLE",
    "type": "ESTETICA",
    "comment": "Se ve el logotipo de otra tienda en la etiqueta"
  }
}

Response · 200

{
  "success": true,
  "data": {
    "assetId": "ast-7c21e5",
    "productId": "PRD-0004812",
    "status": "REJECTED",
    "version": 4,
    "reason": {
      "code": "LOGO_VISIBLE",
      "type": "ESTETICA"
    },
    "rejectedAt": "2026-10-18T17:20:00Z"
  }
}

Errores

HTTPCódigoCuándo
409VERSION_CONFLICTLa imagen cambió desde que se revisó
422VALIDATION_ERROREl motivo no existe para ese tipo de activo
403AUTHORIZATION_ERRORQuien llama no tiene una tarea de revisión abierta sobre el producto
POST /internal/assets/bulk-load · Carga de activos migrados
CampoValor
APIAPI-11-016 · MS-11 Activos digitales
Para quéMS-03 registra los activos que ya existen en P360 con su URL de trabajo y su URL congelada, sin copiar archivos ni cambiar URL; queda un registro por archivo y lo que no se puede aparear queda como incidencia. No publica eventos.
En esta épicaLa migración (FT-MIG-03) carga los activos de P360 con su URL de trabajo y su URL congelada, sin copiar archivos
Quién la llamaMS-03 Migración y convivencia
PermisoSólo MS-03 (cuenta de servicio)
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enassets
También la usanFT-MIG-03

Request

{
  "runId": "mig-run-0007",
  "items": [
    {
      "legacyKey": "P360:1000004812:ProductImageDetail:0000.0002.RK",
      "productId": "PRD-0004812",
      "variantId": "VAR-0004812-01",
      "assetType": "DETALLE",
      "position": 2,
      "workUrl": "cdn.ejemplo.mx/i/trabajo-1000004812_1p.jpg",
      "frozenUrl": "cdn.ejemplo.mx/i/1000004812_1p.jpg",
      "frozenName": "1000004812_1p.jpg"
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "runId": "mig-run-0007",
    "loaded": 1,
    "skipped": 0,
    "issues": []
  }
}

Errores

HTTPCódigoCuándo
409IDEMPOTENCY_MISMATCHEl mismo lote llega otra vez con contenido distinto
422VALIDATION_ERRORUn renglón no trae tipo o producto; se reporta como incidencia y no detiene el lote

Las que usa y construye otra épica (9)

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-11-003POST /api/v2/asset-plans/{planId}/applyConfirmar el plan de la galeríaFT-ACT-01 · Tipos de activo digital y reglas de imágenes por…
API-11-014GET /api/v2/assets/compliance?productId=&stage=Revisar el mínimo antes de cerrar la tareaFT-ACT-01 · Tipos de activo digital y reglas de imágenes por…
API-02-027GET /api/v2/workflow/capabilities?productIds=El motor dice si quien carga puede cambiar las imágenes del producto en su estado y tareaFT-FLU-01 · Motor de estados configurable con dos carreteras y reglas…
API-02-028POST /api/v2/workflow/actions/plansPlan de la acción SUBMIT_IMAGES que cierra Carga de imagenFT-FLU-01 · Motor de estados configurable con dos carreteras y reglas…
API-02-057POST /api/v2/product-plans/{planId}/applyConfirmar la acciónFT-FLU-01 · Motor de estados configurable con dos carreteras y reglas…
API-02-020GET /api/v2/products/{id}/mediaLa copia de imágenes que guarda Producto, para la ficha y la publicaciónFT-PRD-01 · Modelo canónico de producto
API-14-006GET /api/v2/help/articles?q=&screen=La pantalla de carga muestra la ayuda de cómo deben ser las fotosFT-RAC-05 · Estatus del producto y motivos visibles para seller y…
API-14-007GET /api/v2/help/articles/{articleId}Leer el artículo de ayuda de la ficha técnicaFT-RAC-05 · Estatus del producto y motivos visibles para seller y…
API-14-003GET /api/v2/notifications/preferencesLas preferencias del proveedor para los avisos de imagen (el de rechazo es obligatorio)FT-RAC-05 · Estatus del producto y motivos visibles para seller y…

6. Eventos

Publica

EventoCuándoQuién lo consume
catalog.asset.changed/ASSET_UPLOADEDUn archivo llegó al almacénFT-ACT-05
catalog.asset.changed/ASSET_VALIDATEDUn archivo cumple su fichaFT-FLU-07, FT-PRD-07, FT-PRD-08, FT-PRD-10
catalog.asset.changed/ASSET_REJECTEDUn archivo no cumple su ficha o QA rechaza una imagenFT-ACT-03, FT-ACT-05, FT-RAC-04, FT-RAC-06
catalog.asset.changed/ASSET_FROZENUn activo de un producto con SKU queda congelado con su nombre finalFT-ACT-03, FT-ACT-04, FT-ACT-06, FT-ARQ-02, FT-IA-04
catalog.asset.changed/ASSET_DELETEDSe quita una imagen de la galeríaMS-05 (bitácora)
catalog.asset.changed/ASSET_JOB_FINISHEDTermina una carga masiva de imágenesMS-05 (bitácora)
catalog.product.changed/MEDIA_CHANGEDProducto actualizó su copia de URL congeladasFT-IA-05
catalog.product.changed/TASK_CHANGEDSe cierra Carga de imagenFT-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
catalog.product.publication/PUBLICATION_REQUESTEDCambió la galería de un producto ya publicadoFT-CAT-05, FT-CAT-06, FT-INT-01, FT-INT-02, FT-INT-05, FT-INT-07, FT-PLT-08, FT-PRD-05, FT-RAC-03

Consume

EventoPara quéQuién lo publica
catalog.product.changed/SKU_ASSIGNEDMS-11 congela lo que ya estaba cargado con el SKU de cada varianteFT-INT-03, FT-PRD-02
catalog.asset.changed/ASSET_FROZENMS-02 relee la galería y guarda la copia de URL congeladas y «procede»esta misma épica
catalog.asset.changed/ASSET_DELETEDMS-02 relee la galería y quita la URL de su copiaesta misma épica
catalog.asset.changed/ASSET_REJECTEDMS-14 avisa al proveedor; MS-02 registra el rechazo en el producto y lo saca de su copiaesta misma épica
catalog.asset.changed/ASSET_JOB_FINISHEDMS-14 avisa a quien lanzó la carga masivaesta misma épica

7. Datos

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

ColecciónDueñoQué guardaEsta épica
assetsMS-11Cada archivo una vez: a qué producto, variante y posición pertenece, su validación técnica, URL de trabajo y URL congelada.escribe
asset_jobsMS-11Cargas masivas de imágenes, por archivo comprimido, carpeta o lista de URL.escribe
asset_outboxMS-11Los cambios de activos que esperan salir como evento.escribe
productsMS-02La familia del producto con sus variantes, valores, imágenes (URL), clasificaciones, estado, tareas abiertas y rechazos.escribe
tasksMS-02Todo el trabajo asignado: visto bueno, corrección, Gobierno de Datos, foto, secciones, QA, revisión del cambio y repoblamiento.escribe
asset_typesMS-11Los tipos de activo (principal, detalle, isométrica, video, certificado…) con su ficha técnica: medidas, peso, formato, máximo y si se publica.lee
template_viewsMS-01La vista efectiva ya resuelta por plantilla y negocio: qué atributos pide y cuáles son obligatorios.lee

8. Historias que cubre

HistoriaPrioridadCómo la cubre
FT-ACT-02·H1 · Registrar URLsP1pasos 1, 2, 4, 5, 6, 9, 10; API-11-004, API-11-005, API-11-007
FT-ACT-02·H2 · Consultar antes de enviarP1API-11-007
FT-ACT-02·H3 · Publicar la congeladaP1pasos 6, 7, 10; flujo «Congelado al asignar el SKU (la tubería de la imagen)»; API-11-010, API-02-020
FT-ACT-02·H4 · Variante sin principalP1pasos 10, 12; API-11-014
FT-ACT-02·H5 · Cambiar imágenes de un publicadoP2flujo «Rechazar o cambiar imágenes de un producto ya publicado»; API-11-009
FT-ACT-02·H6 · Rechazo por imagenP2flujo «Rechazar o cambiar imágenes de un producto ya publicado»; API-11-015
FT-ACT-02·H7 · PrevisualizarP3API-11-008
FT-ACT-02·H8 · Conservar los canales de cargaP1flujo «Carga masiva de imágenes»; API-11-004, API-11-011, API-11-012
FT-ACT-02·H9 · Activos que no salen a comercioP2API-11-008
FT-ACT-02·H10 · La tubería de la imagenP1pasos 6; flujo «Congelado al asignar el SKU (la tubería de la imagen)»

9. Decisiones de esta épica

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

  • D-ACT-02-1. Se conserva la copia congelada: cada activo tiene su original, su copia de trabajo y, con SKU, su copia congelada con el nombre final. Sólo la congelada se copia al producto y se publica. Por qué: Decide la mitad de PD-21 que toca al congelado: es lo que hoy publica P360 y evita que un cambio en la copia de trabajo llegue a la tienda sin revisión. Se apoya en PD-21, RSG-23, DUD-29.
  • D-ACT-02-2. Se congela al tener SKU: MS-11 escucha SKU_ASSIGNED y congela lo válido; lo que llega después se congela al validarse. Si se reemplaza una imagen ya congelada, la URL nueva lleva su versión para que la tienda no muestre la vieja guardada en caché. Por qué: El nombre final usa el SKU (principal = SKU) y hoy la copia a congelados se dispara con el SKU; la versión en la URL evita depender de borrar la caché de la red de entrega. Se apoya en DUD-29, RF-IMG-12, ADR-12.
  • D-ACT-02-3. MS-11 es dueño de los archivos y de sus URL públicas; MS-02 es dueño de la liga de cada activo con su variante, la principal, el orden, «procede» y la copia de la URL congelada. Con cada evento de activo, MS-02 relee la galería efectiva (API-11-007) en lugar de aplicar cambios sueltos; la URL de trabajo y la validación se leen en MS-11. Por qué: Una sola entrada de activos para el portal, el estudio y los sellers, y Producto sigue siendo el dueño de lo que se publica. Releer todo hace al consumidor inmune al orden y a los repetidos. Se apoya en DUD-29, ADR-12, FT-PRD-01.
  • D-ACT-02-4. Carga de imagen se cierra cuando el proveedor envía (acción SUBMIT_IMAGES del motor) y el plan confirma el mínimo de aprobación de su plantilla y negocio con API-11-014; si vence el plazo de FT-PRD-08, el reloj de MS-02 la cierra como vencida y abre Foro por rescate (FT-ACT-05). MS-02 sólo abre esta tarea si la revisión de aprobación no pasa al asignarse el SKU. Por qué: El TO-BE pregunta «¿el proveedor la envió a QA?»; cerrar sola al primer mínimo cortaría al proveedor que sigue subiendo fotos, y abrirla cuando ya cumple sería trabajo de más. Se apoya en PD-29, FT-FLU-01, FT-PRD-08.
  • D-ACT-02-5. Los binarios nunca pasan por el BFF ni por MS-02: la pantalla o el agente suben directo al almacén con una URL firmada de 15 minutos que da MS-11 después de preguntar al motor si quien carga puede cambiar las imágenes (API-02-027). Por qué: El BFF compone pantallas y no mueve archivos pesados; el permiso de dominio lo decide el motor de MS-02 y MS-11 lo aplica antes de firmar. Se apoya en ADR-12, DUD-33.
  • D-ACT-02-6. Cambiar imágenes de un producto publicado no lo regresa a captura: la imagen pasa la validación técnica, se congela y MS-02 pide republicar sólo sus canales. Lo pueden hacer el dueño del contenido, el estudio si la foto es de Liverpool y Repoblamiento; QA rechaza una imagen sola con API-11-015. Por qué: Lo pide la ERF (alta, cambio y baja sin revalidar) y deja propuesta la regla de P-35 mientras la ERF de flujos no exista. Se apoya en P-35, DUD-09.
  • D-ACT-02-7. Los activos de respaldo (certificado sostenible, carta responsiva) y los bocetos no tienen URL pública: viven en la zona privada del almacén y sólo los roles de su tipo los ven, con URL firmada de 10 minutos. Por qué: S16: son respaldo, no salen a comercio ni generan URL; una URL pública los dejaría a la vista de cualquiera. Se apoya en S16-RF-01, DUD-33.
  • D-ACT-02-8. LasImagenes2 y KeepFinalMediaAssetURLs2 no se construyen (decisión 20): las pantallas del portal pasan al BFF en R1 y el estudio deja de copiar al bucket y de avisar dos veces. Los canales de carga de hoy (portal, estudio, generador de links y carga desde bucket) se conservan como pruebas de no afectación sobre MS-11. Por qué: Una foto de Foro hoy llega dos veces a P360 por dos caminos; con un solo registro no hay nada que reconciliar. Se apoya en ADR-12, PD-06, RSG-29.
  • D-ACT-02-9. Ninguna URL lleva cadenas pegadas ni credenciales: el acceso a lo privado es por URL firmada que vence, nunca por un texto fijo concatenado a la URL. Por qué: La cadena que hoy se pega a la URL podría ser un token (PEN-145); con URL firmadas deja de hacer falta. Se apoya en PEN-145, RSG-44.
  • D-ACT-02-10. Avisos (MS-14): se entera de qué avisar consumiendo eventos (ASSET_REJECTED, ASSET_JOB_FINISHED, STATUS_CHANGED, REJECTION_ADDED, TASK_CHANGED) y por API-14-005 cuando no basta un evento; resuelve a quién le llega con el directorio de MS-13 sin copiar correos; guarda las preferencias de cada persona como su documento de ajustes en notifications; un aviso obligatorio (rechazo, plazo por vencer) no se puede apagar, y la misma llave de duplicado no repite el aviso. Por qué: Un solo lugar para avisar a proveedores, sellers, estudio y áreas, sin el correo y las notificaciones duplicados de Entrada Única y Foro; las preferencias son de MS-14 y no hay otra colección suya donde guardarlas. Se apoya en P-02, PEN-17, ADR-12.

Qué falta decidir

IDQué falta
PD-21Sigue abierta la mitad del seller (URL propias o carga por Entrada Única); aquí se propone conservar la copia congelada.
DUD-29Arquitectura con Publicación confirma en ADR-04 que MS-11 es dueño de las URL públicas que sirve la red de entrega.
P-35Prod E-commerce con Foro confirma quién cambia una imagen publicada y si vuelve a calidad.
DUD-09La ERF de flujos sigue sin escribirse; aquí se propone cambiar imágenes publicadas sin revalidar.
DUD-33Seguridad revisa la carga directa al almacén con URL firmada y la credencial de equipo del agente.

Fuentes

  1. [D] trazabilidad/features/FT-ACT-02-registro-congelado-publicacion-urls.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.