Actualizado el 18-oct-2026. Primera versión de la arquitectura de esta épica.
Qué responde. Cómo funciona por dentro FT-ARQ-01: 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-ARQ-01.json, generada con generar.py; la ficha de la épica es trazabilidad/features/FT-ARQ-01-nucleo-headless-api-unica-producto.md.
En 30 segundos
El núcleo del PIM tiene una sola API de producto: los servicios de MS-02. Da igual si el alta llega de una pantalla, de un archivo, del sistema de un seller o de la migración: pasa por las mismas validaciones, nace igual en Borrador con su origen y sale una sola vez como evento. Las pantallas llegan a esa API por el BFF del portal y los sistemas de terceros por el gateway; ninguna de las dos puertas guarda datos ni decide reglas.
- Módulo dueño: MS-02 Producto. También participan: MS-01 Catálogo, MS-06 Evaluación, MS-13 Identidad y acceso, MS-05 Auditoría, MS-03 Migración y convivencia.
- Etapa T · Transversal. Recibe «PE-C · Catálogo vigente» y entrega «PE-1 · Propuesta en Borrador».
- APIs: construye 2 y usa 15 que construyen otras épicas.
- Eventos: publica 2 y consume 1.
1. Dónde encaja
Recibe
| De | Qué |
|---|---|
| FT-PRD-01 · Modelo canónico de producto | El modelo canónico: la familia con sus variantes en un solo documento, sus tipos, banderas y llaves (SKU y EAN por negocio). |
| FT-USR-01 · Identidad y autenticación de usuarios internos… | La identidad de cada llamada: el token que validan el BFF, el gateway y cada servicio, y los roles del directorio de MS-13. |
| PE-C · Catálogo vigente | La vista efectiva de cada plantilla por negocio, contra la que se valida toda alta y todo cambio. |
| FT-MIG-04 · Convivencia P360 ↔ nuevo PIM | La escritura en P360 por MS-03 (API-03-009 y API-03-010) que usa la API de producto mientras P360 sea la fuente. |
Entrega
| A | Qué |
|---|---|
| PE-1 · Propuesta en Borrador | Toda alta confirmada, venga de la pantalla, de un archivo o de la API de terceros, deja un producto en Borrador con negocio, origen y dueño, y su evento PRODUCT_CREATED. |
| FT-PRD-09 · Contrato de propuestas con Entrada Única | La API de producto que usan las pantallas de propuesta a través del BFF. |
| FT-PRD-10 · Catalogación por API del proveedor o seller | La misma API detrás del gateway de terceros, con el alta completa en un paso y el envío al confirmar. |
| FT-FLU-04 · Carga masiva de productos por archivo | La misma alta completa para cada renglón válido de la carga masiva. |
| FT-ACT-05 · Servicios para Foro Fotográfico | La consulta por SKU o EAN con su familia (API-02-201) para los servicios del estudio. |
| FT-MIG-03 · Migración inicial de productos desde P360 | La carga interna por llave de negocio y sin eventos (API-02-056) para la migración inicial desde P360. |
Cambios de estado que hace
| Transición | De → a | Cuándo |
|---|---|---|
| T01 | Inicio → Borrador | El proveedor o seller guarda por primera vez (pantalla, archivo, plantilla en línea o API). |
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
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.
Los pasos en texto
| Paso | De | A | Qué hace | API o evento |
|---|---|---|---|---|
| 1 | Proveedor | Entrada Única · Vendor Center | Captura los datos de su propuesta y la guarda | — |
| 2 | Entrada Única · Vendor Center | BFF del portal | Manda el alta con la sesión del usuario | — |
| 3 | BFF del portal | MS-02 Producto | Pide identificar el producto antes del alta | API-02-202 |
| 4 | MS-02 Producto | MS-06 Evaluación | Pide la evaluación común de lista negra y coincidencias | API-06-001 |
| 5 | BFF del portal | MS-02 Producto | Pide el plan del alta con origen PORTAL | API-02-005 |
| 6 | MS-02 Producto | MS-13 Identidad y acceso | Pide los permisos efectivos de quien llama | API-13-001 |
| 7 | MS-02 Producto | MS-01 Catálogo | Valida contra la vista efectiva de la plantilla | API-01-028 |
| 8 | BFF del portal | MS-02 Producto | Confirma el plan sin cambios | API-02-057 |
| 9 | MS-02 Producto | Base pim | Guarda propuesta, evaluación, recibo y outbox juntos | — |
| 10 | MS-02 Producto | Eventos | Publica el alta una sola vez | catalog.product.changed/PRODUCT_CREATED |
| 11 | Eventos | MS-05 Auditoría | Entrega el alta para la bitácora | catalog.product.changed/PRODUCT_CREATED |
| 12 | BFF del portal | MS-02 Producto | Lee el recibo con los ID creados | API-02-025 |
3.1 La misma alta por la API de terceros
3.2 Consulta por SKU o EAN, sin editar
3.3 Carga de la migración, sin eventos
4. Si algo sale mal
- Llega una llamada sin token o con un token vencido. El BFF o el gateway responden 401 sin tocar ningún servicio; si algo llega por dentro a un servicio sin token válido, el servicio también lo rechaza (ADR-05). Nadie confía en cabeceras de roles.
- Alguien cambió la propuesta o su plantilla entre el plan y la confirmación. La confirmación responde 409 VERSION_CONFLICT o PLAN_EXPIRED; la pantalla o el tercero piden el plan otra vez sobre la versión nueva y nada queda a medias.
- MS-06 no responde al evaluar. La identificación responde 503 DEPENDENCY_UNAVAILABLE y no se crea nada; la pantalla o el tercero reintentan. Si el evaluationId venció (24 horas) antes de crear, MS-02 evalúa otra vez al crear la propuesta.
- Falla la salida de un evento. El evento está en el outbox de MS-02, guardado en la misma transacción que el cambio: se reintenta hasta salir y nunca se pierde; quien lo consume descarta el eventId repetido.
- La migración trae un EAN que ya usa otro SKU. Ese registro sale rechazado con EAN_IN_USE en el resultado del lote y MS-03 lo deja en sus incidencias; los demás registros del lote sí se cargan.
5. APIs
Las que construye esta épica (2)
GET /api/v2/products/by-identifier · Producto por SKU o EAN, con su familia
| Campo | Valor |
|---|---|
| API | API-02-201 · MS-02 Producto |
| Para qué | Devuelve la familia completa (genérico y variantes) a partir del SKU o el EAN de cualquier variante, con los atributos de producto y de variante separados, y distingue «no existe» de «existe con error». |
| En esta épica | Producto por SKU o EAN con su familia; distingue «no existe» de «existe con error» |
| Quién la llama | Entrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF), Gateway de terceros /partner/v1 |
| Permiso | ENT-L; el proveedor o seller sólo ve sus productos |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | sku = 1000004813, ean = None, business = MER |
| También la usan | FT-ACT-05, FT-PRD-09 |
Request
null
Response · 200
{
"success": true,
"data": {
"productId": "PRD-0004812",
"business": "MER",
"status": "EN_ENRIQUECIMIENTO",
"version": 9,
"origin": "PORTAL",
"matchedBy": {
"type": "SKU",
"value": "1000004813",
"variantId": "VAR-0004812-02"
},
"templateId": "EU4-0412",
"productAttributes": {
"TITULO": "Licuadora de 10 velocidades",
"MARCA": "MARCA01",
"MODELO": "LV-10"
},
"variants": [
{
"variantId": "VAR-0004812-01",
"sku": "1000004812",
"ean": "7501234567893",
"variantAttributes": {
"COLOR": "ROJO"
}
},
{
"variantId": "VAR-0004812-02",
"sku": "1000004813",
"ean": "7501234567909",
"variantAttributes": {
"COLOR": "NEGRO"
}
}
],
"issues": [
{
"variantId": "VAR-0004812-02",
"code": "SAP_ERROR",
"message": "SAP rechazó el artículo (141): falta el grupo de artículo"
}
]
}
}
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 404 | NOT_FOUND | Ningún producto tiene ese SKU o EAN en ese negocio: no existe |
| 400 | VALIDATION_ERROR | Falta el SKU o el EAN, vienen los dos o el EAN no tiene un dígito verificador válido |
POST /internal/product/bulk-load/products · Carga interna de la migración
| Campo | Valor |
|---|---|
| API | API-02-056 · MS-02 Producto |
| Para qué | MS-03 carga productos de P360 por lotes: inserta o actualiza por llave de negocio, con su estado, su estado por canal y origen MIGRATION, y reserva SKU y EAN en el registro de identidad. No publica eventos: replica lo que ya existía. |
| En esta épica | Carga interna de la migración por llave de negocio, sin eventos |
| Quién la llama | MS-03 Migración y convivencia |
| Permiso | Sólo MS-03 (cuenta de servicio) |
| Cabeceras | Authorization, X-Request-Id, Idempotency-Key |
| Escribe en | products, identifier_registry, product_versions, product_delivery_status, product_receipts |
| También la usan | FT-MIG-03, FT-MIG-04, FT-MIG-05, FT-PRD-01 |
Request
{
"runId": "mig-run-0007",
"batch": 12,
"records": [
{
"legacyId": "P360-1100-883421",
"businessKey": {
"business": "MER",
"sku": "1000004812"
},
"status": "APROBADO",
"templateId": "EU4-0412",
"product": {
"TITULO": "Licuadora de 10 velocidades",
"MARCA": "MARCA01",
"MODELO": "LV-10"
},
"variants": [
{
"legacyId": "P360-1000-883422",
"sku": "1000004812",
"ean": "7501234567893",
"axes": {
"COLOR": "ROJO"
}
}
],
"channels": [
{
"channel": "TIENDA",
"state": "Publicado",
"lastSentAt": "2026-09-30T11:20:00Z"
}
]
}
]
}
Response · 200
{
"success": true,
"data": {
"runId": "mig-run-0007",
"batch": 12,
"inserted": 98,
"updated": 2,
"rejected": 1,
"items": [
{
"legacyId": "P360-1100-883421",
"result": "INSERTED",
"productId": "PRD-0004812"
},
{
"legacyId": "P360-1100-883499",
"result": "REJECTED",
"code": "EAN_IN_USE",
"message": "El EAN ya está registrado en MER con otro SKU"
}
]
}
}
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 409 | IDEMPOTENCY_MISMATCH | El mismo lote llega otra vez con otro contenido |
| 422 | VALIDATION_ERROR | Un registro no trae la llave de negocio o su plantilla no existe |
| 413 | LIMIT_EXCEEDED | Más de 1,000 registros en un lote |
Las que usa y construye otra épica (15)
Su request y su response están en la página de la épica que la construye.
| API | Método y ruta | Para qué, aquí | La construye |
|---|---|---|---|
| API-02-005 | POST /api/v2/products/plans | Alta en Borrador desde cualquier puerta, paso a paso | FT-PRD-01 · Modelo canónico de producto |
| API-02-006 | POST /api/v2/products/guided/plans | Alta completa en un paso (sin productId) para archivo y API de terceros, con origen y envío al confirmar | FT-PRD-07 · Captura guiada por pasos con los mínimos primero |
| API-02-057 | POST /api/v2/product-plans/{planId}/apply | Confirmar cualquier plan de Producto | FT-FLU-01 · Motor de estados configurable con dos carreteras y reglas… |
| API-02-025 | GET /api/v2/product-receipts/{requestId} | Leer el recibo de la operación confirmada | FT-FLU-01 · Motor de estados configurable con dos carreteras y reglas… |
| API-02-012 | POST /api/v2/products/{id}/values/plans | Cambiar valores con la misma validación en el momento, venga de donde venga | FT-RAC-01 · Motor de validación en línea y candados de datos… |
| API-13-001 | GET /internal/identity/permissions?userId= | Permisos efectivos de quien llama, con caché | FT-USR-01 · Identidad y autenticación de usuarios internos… |
| API-13-012 | GET /internal/identity/partners/by-client/{clientId} | El tercero de un cliente de API, con su estado y sus límites | FT-USR-03 · Control de acceso por API para terceros |
| API-01-028 | GET /api/v2/taxonomies/PRODUCT/nodes/{id}/effective | Vista efectiva de la plantilla por negocio | FT-PLT-06 · Configuración de atributos por plantilla y por negocio… |
| API-06-001 | POST /api/v2/evaluations | Evaluación común de lista negra, coincidencias y decisión por negocio | FT-REF-02 · Blacklist de Marketplace por marca, negocio y grupo de… |
| API-06-005 | POST /api/v2/matches | Buscar duplicados por EAN o por marca y modelo antes del alta | FT-REF-03 · Servicio de matching |
| API-02-102 | POST /api/v2/products/ean-checks | Revisar EAN al capturarlos, sin reservarlos | FT-PRD-03 · EAN |
| API-GW-001 | POST /partner/v1/proposals | La puerta de terceros que traduce a la misma alta | FT-PRD-10 · Catalogación por API del proveedor o seller |
| API-02-001 | POST /api/v2/products/search | Búsqueda con filtros combinados (estado y negocio) | FT-PRD-01 · Modelo canónico de producto |
| API-02-027 | GET /api/v2/workflow/capabilities?productIds= | Qué puede editar quien llama: con sólo consulta, nada | FT-FLU-01 · Motor de estados configurable con dos carreteras y reglas… |
| API-02-202 | POST /api/v2/products/identifications | Identificación previa al alta: evaluación común sin crear nada; deja un evaluationId de 24 horas | FT-FLU-02 · Alta individual de Marketplace |
6. Eventos
Publica
| Evento | Cuándo | Quién lo consume |
|---|---|---|
catalog.product.changed/PRODUCT_CREATED | Se confirma un alta de cualquier origen | MS-05 (bitácora) |
catalog.product.changed/PRODUCT_UPDATED | Se confirma un cambio de cualquier origen | FT-ACT-05, FT-ARQ-02, FT-IA-01, FT-PLT-07, FT-PRD-05, FT-RAC-06 |
Consume
| Evento | Para qué | Quién lo publica |
|---|---|---|
catalog.product.changed/PRODUCT_CREATED | MS-05 guarda en la bitácora quién dio de alta, desde qué puerta y con qué origen | esta misma épica |
7. Datos
Cada colección tiene un solo dueño, el único que escribe en ella.
| Colección | Dueño | Qué guarda | Esta épica |
|---|---|---|---|
products | MS-02 | La familia del producto con sus variantes, valores, imágenes (URL), clasificaciones, estado, tareas abiertas y rechazos. | escribe |
identifier_registry | MS-02 | Unicidad de SKU y de EAN por negocio. | escribe |
product_versions | MS-02 | Foto numerada del producto en cada versión. | escribe |
product_delivery_status | MS-02 | El estado de publicación por producto y canal: Pendiente, Enviado, Publicado, Error o Retirado. | escribe |
product_receipts | MS-02 | El recibo de cada escritura confirmada en el producto (antes operation_receipts). | escribe |
product_outbox | MS-02 | Los cambios del producto que esperan salir como evento (antes outbox). | escribe |
template_views | MS-01 | La vista efectiva ya resuelta por plantilla y negocio: qué atributos pide y cuáles son obligatorios. | lee |
validation_results | MS-06 | El resultado de cada evaluación: lista negra, coincidencias con su confianza y score. | lee |
roles | MS-13 | Perfiles y roles, con sus membresías y su alcance (negocio, sección, proveedor o seller, vigencia). Los permisos de dominio los decide el servicio dueño con estos roles (decisión 19). | lee |
partners | MS-13 | El registro de terceros: proveedores y sellers que llaman por API, con su tipo, negocios, tiendas, alcances, límites y clientes (catalogación por API §3.1). | lee |
8. Historias que cubre
| Historia | Prioridad | Cómo la cubre |
|---|---|---|
| FT-ARQ-01·H1 · Dar de alta o modificar un producto por la misma API | P1 | pasos 1, 3, 4, 5, 7, 8, 9, 10; flujo «La misma alta por la API de terceros»; API-02-005, API-02-006 |
| FT-ARQ-01·H2 · Consultar un producto por ID, SKU o EAN con su familia | P1 | flujo «Consulta por SKU o EAN, sin editar»; API-02-201 |
| FT-ARQ-01·H3 · Seguir creando, consultando y modificando propuestas al apagar P360 | P1 | API-02-005, API-02-012, API-02-001. Fuera: El paso de las pantallas de propuesta de Entrada Única al BFF y el apagado de los servicios de P360 que usan hoy lo resuelve FT-PRD-09 (R2); aquí se garantiza que la API cubre crear, consultar y modificar. |
| FT-ARQ-01·H4 · Buscar por EAN o por marca y modelo | P2 | API-02-202, API-06-005, API-02-102 |
| FT-ARQ-01·H5 · Que un cambio hecho en cualquier canal se aplique una vez y llegue a los… | P2 | pasos 9, 10, 11 |
| FT-ARQ-01·H6 · La lógica vive en el backend | P1 | pasos 3, 4, 6, 7 |
| FT-ARQ-01·H7 · Consultar la ficha completa sin editarla | P2 | flujo «Consulta por SKU o EAN, sin editar»; API-02-001, API-02-027 |
9. Decisiones de esta épica
Las tomó el TL como arquitecto; quedan como [Propuesta] hasta que el equipo de la épica las revise.
- D-ARQ-01-1. La API única de producto son los servicios de MS-02 (/api/v2/products…, con plan y confirmación). Las pantallas llegan por el BFF del portal y los sistemas de terceros por el gateway /partner/v1; ninguna de las dos puertas guarda datos ni decide reglas, y los servicios no se exponen a internet. Por qué: Un solo dueño del dato y de la regla: si cada puerta validara por su cuenta habría tantas reglas como canales, que es lo que hoy pasa entre Entrada Única y P360. Se apoya en ADR-12, ADR-05, PD-05, PD-26, RF-GEN-01, RF-GEN-10.
- D-ARQ-01-2. Toda alta pasa por las mismas operaciones de MS-02, con los mismos validadores contra la vista efectiva: primero la identificación (API-02-202), que pide a MS-06 la evaluación común sin crear nada; después el alta, paso a paso desde la pantalla (API-02-005 y luego plantilla, valores y variantes) o completa en un paso para archivo y API de terceros (API-02-006 sin productId). La propuesta nace en Borrador con su evaluationId (vale 24 horas; si venció, MS-02 evalúa otra vez); en la carga masiva la evaluación es por bloque (API-06-002). La Validación automática vuelve a evaluar al enviar. Por qué: Una alta en pantalla y la misma por archivo dan el mismo resultado (RF-MAT-20) y el SKU se crea igual por cualquier canal; si ya existe o la marca está vetada no nace nada, y la propuesta llega a PE-1 con lo que pide PE-2 ya guardado. Se apoya en RF-GEN-01, RN-ALT-12, DEC-59, DEC-62, RF-MAT-20.
- D-ARQ-01-3. El alta completa (API-02-006 sin productId) recibe un bloque intake con el origen (BULK o PARTNER_API), el tercero, su externalRef y, si ya se evaluó por bloque, el evaluationId; y acepta thenAction = SUBMIT para que, al confirmar, si está completa, se envíe a revisión en la misma operación. La pantalla sigue con su botón Enviar (API-02-028). Por qué: Un renglón o un tercero que mandan todo de una vez no deben necesitar ocho llamadas ni quedar a medias; así el gateway es un traductor sin estado. Se pide a quienes construyen API-02-006 y la confirmación (API-02-057) que lo acepten. Se apoya en DUD-38, RN-ENR-13, ADR-12.
- D-ARQ-01-4. El origen viaja en el producto, en cada valor y en el sobre de cada evento: PORTAL, BULK, PARTNER_API, SAP, IA o MIGRATION. Lo que propone la IA queda con origen IA y sin confirmar hasta que el usuario lo acepta. Por qué: Cumple H1 (lo prellenado por IA requiere confirmación) y permite que gane lo que mandó el dueño del contenido; DEC-65 ya pedía registrar el origen de toda actualización. Se apoya en DEC-65, PEN-167, RN-ENR-13.
- D-ARQ-01-5. Cada escritura confirmada guarda el cambio, el recibo y el evento del outbox en la misma transacción, y el evento sale una sola vez; los consumidores descartan el eventId repetido. El núcleo no manda avisos a sistemas viejos: los idmc_ los decide FT-INT-06 sólo mientras quede un consumidor que no sea el portal. Por qué:* H5: un cambio hecho en cualquier canal se aplica una vez y llega a todos; con el portal leyendo del PIM por el BFF, Entrada Única ya no necesita copias ni avisos. Se apoya en ADR-12, PD-06, RSG-26.
- D-ARQ-01-6. La consulta por SKU o EAN de cualquier variante es una ruta propia (API-02-201) que lee el registro de identidad y devuelve la familia con los atributos de producto y de variante separados; «no existe» es 404 y «existe con error» es 200 con issues[]. La meta de 50 ms p95 queda sin dato hasta la prueba de carga. Por qué: Es la lectura más frecuente de los consumidores (estudio, gateway, Gobierno de Datos) y no debe depender de la búsqueda general; cumple el criterio de RF-INT-04. Se apoya en RF-INT-04, DEC-PRD-02.
- D-ARQ-01-7. La carga de la migración (API-02-056) es interna, sólo para MS-03, por llave de negocio, sin plan ni eventos: replica lo que ya existía en P360 con su estado y su estado por canal, y el producto entra al hilo en PE-M. Por qué: Publicar millones de altas que no son altas saturaría a todos los consumidores; la trazabilidad de la carga la llevan las corridas de MS-03. Se apoya en ADR-08, FT-MIG-03.
- D-ARQ-01-8. Las reglas de validación viven en MS-02 contra la vista efectiva de MS-01, y la lista negra, las coincidencias y el score en MS-06; el BFF sólo compone y aplica permisos de pantalla, y el front sólo muestra. Un rol sólo de consulta ve la ficha completa: capabilities devuelve todo de sólo lectura y ninguna acción. Por qué: Responde H6 (la lógica vive en el backend) y H7 (consultar sin arriesgar un cambio), y cierra PD-05 y RF-GEN-10 con ADR-12 y la decisión 19. Se apoya en PD-05, RF-GEN-10, DEC-PRD-08, ADR-12.
Qué falta decidir
| ID | Qué falta |
|---|---|
| PD-26 | Arquitectura con Seguridad confirma el proveedor de identidad para tokens de máquina a máquina y los límites por puerta en la entrada del clúster. |
| P-05 | Compras con SAP decide si PLM, MM41 y B2B siguen naciendo en SAP o entran por la API del PIM; aquí se asume SAP (FT-INT-03). |
| DUD-38 | Prueba de carga de plan y confirmación en MS-02 con la evaluación de MS-06, para fijar si el alta individual por API responde en línea. |
También siguen abiertos: PEN-05, Confirmar qué orígenes entran al núcleo en el primer corte; las altas que hoy nacen en SAP siguen llegando por el 122.
Fuentes
- [D]
trazabilidad/features/FT-ARQ-01-nucleo-headless-api-unica-producto.md: la ficha de la épica, con sus historias, reglas y bloqueos. - [D] ADR-12 · Un solo sistema: backend compartido y una sola base (sección 3.4).
- [D]
docs/arquitectura/por-epica/base/: piezas, colecciones, eventos y el hilo de punta a punta. - [D]
docs/arquitectura/omega-a-pim-headless/contratos-api.md: convenciones y endpoints de partida. - [D]
docs/arquitectura/maquina-de-estados-to-be/propuesta-maquina-de-estados.md§7: estados, tareas y canales. - [I] Las decisiones de la sección 9 son del TL sobre esas fuentes.