← Arquitectura por épica

FT-PLT-01 · Fundamentos de gobierno de plantillas

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-PLT-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-PLT-01.json, generada con generar.py; la ficha de la épica es trazabilidad/features/FT-PLT-01-fundamentos-de-gobierno-de-plantillas.md.

En 30 segundos

Plantillas, atributos y listas las usan todos los portales y SAP, así que un cambio mal hecho afecta a miles de productos. Esta épica pone las reglas comunes de toda escritura del catálogo: cada objeto conserva su identificador para siempre, todo cambio queda como solicitud pendiente hasta que otra persona autorizada lo aprueba, y cada campo cambiado deja su antes y su después en la bitácora. Así nada llega a la captura sin control y siempre se sabe quién cambió qué.

  • Módulo dueño: MS-01 Catálogo. También participan: MS-13 Identidad y acceso, MS-14 Avisos y ayuda, MS-05 Auditoría, MS-02 Producto, MS-03 Migración y convivencia, MS-15 IA y enriquecimiento.
  • Etapa C · Configura el catálogo. Recibe «PE-T · Usuario con permisos y bitácora» y entrega «PE-C · Catálogo vigente».
  • APIs: construye 8 y usa 7 que construyen otras épicas.
  • Eventos: publica 1 y consume 2.

1. Dónde encaja

Recibe

DeQué
PE-T · Usuario con permisos y bitácoraEl usuario ya identificado, con sus roles del directorio de MS-13 y la bitácora de MS-05 lista para guardar cada cambio.
FT-USR-02 · Matriz de roles y permisos por módulo, acción, negocio y…La hoja del catálogo de la matriz firmada (qué rol consulta, propone, aprueba o captura un ID en cada tipo de objeto y negocio), que Seguridad carga en MS-01 con API-01-110.
FT-ARQ-02 · Bitácora inmutable y versionado de producto, plantilla y…La bitácora inmutable de MS-05, que guarda cada evento del catálogo con el antes y el después por campo.
FT-IA-04 · Integración de los modelos de IA existentesLa plantilla que propone la IA, como solicitud de cambio con canal IA que Gobierno de Producto aprueba o rechaza.

Entrega

AQué
PE-C · Catálogo vigenteSólo lo aprobado entra al catálogo vigente: cada cambio aplicado sale en catalog.governance.changed con su versión y sus cambios por campo.
FT-PLT-02 · Catálogo de atributosEl mecanismo común de escritura (plan, solicitud, aprobación, recibo e identificadores) para el catálogo de atributos.
FT-PLT-05 · Taxonomía de plantillas por familia, metadatos de…El mismo mecanismo para el árbol de plantillas, con la secuencia EU{nivel+1}-{número} que asigna el ID al aprobar.
FT-PLT-09 · Carga masiva de configuración de plantillas con…La solicitud de cambio con canal IMPORT, API o IA, para que una carga masiva siga el mismo control que la pantalla.
FT-PLT-07 · Reglas de atributosLa confirmación común de planes (API-01-004) y, para las reglas que pidan aprobación, la solicitud y su decisión (API-01-103).
FT-MIG-02 · Migración de plantillas, atributos y listas de valoresLa ruta de carga de la migración (API-01-053): conserva los ID de P360, no publica eventos y deja la secuencia en el máximo migrado más uno.

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

Plan de cambio de nodos
Confirmar un plan del catálogo
y 4 más

Roles efectivos de quien llama

Mandar un aviso explícito

TEMPLATE_CHANGED

TEMPLATE_CHANGED

TEMPLATE_CHANGED

Subir una carga para validarla
Aplicar una carga validada

Carga de la migración

Rechaza el plan con IMMUTABLE_ID

Historia de un objeto

permisos

bitácora

Administración del catálogo

Entrada Única · Vendor Center

BFF del portal

★ MS-01 Catálogo

MS-13 Identidad y acceso

MS-14 Avisos y ayuda

MS-05 Auditoría

MS-02 Producto

MS-03 Migración y convivencia

MS-15 IA y enriquecimiento

Base pim

Eventos

Contexto de FT-PLT-01

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-02 ProductoMS-05 AuditoríaEventosMS-14 Avisos y ayudaBase·pimMS-13 Identidad y accesoMS-01 CatálogoEntrada Única · Vendor CenterMS-02 ProductoMS-05 AuditoríaEventosMS-14 Avisos y ayudaBase·pimMS-13 Identidad y accesoMS-01 CatálogoEntrada Única · Vendor CenterAdministración del catálogoBFF1. Da de alta una plantilla nueva sin capturar su ID2. Pide el plan del alta bajo su familiaPOST /api/v2/structures/{id}/nodes/plans3. Pide los roles del usuario y los cruza con su matrizGET /internal/identity/permissions?userId=4. Confirma el plan y abre la solicitud de cambioPOST /api/v2/catalog-plans/{planId}/apply5. Guarda la solicitud pendiente con su antes y después6. Avisa a los aprobadores que hay una solicitudPOST /internal/notifications/messages7. Otro administrador abre su bandeja de solicitudes8. Lista las solicitudes pendientes que puede decidirGET /api/v2/catalog-change-requests9. Abre el cambio campo por campoGET /api/v2/catalog-change-requests/{changeRequestId}10. Aprueba la solicitudPOST /api/v2/catalog-change-requests/{changeRequestId}/decision11. Asigna el siguiente EU4 y crea la plantilla activa12. Avisa el alta de la plantillaTEMPLATE_CHANGED13. Entrega el cambio para la bitácora por campoTEMPLATE_CHANGED14. Entrega el cambio: la captura ya puede ofrecerlaTEMPLATE_CHANGEDAdministración del catálogoBFF
Flujo principal de FT-PLT-01
Los pasos en texto
PasoDeAQué haceAPI o evento
1Administración del catálogoEntrada Única · Vendor CenterDa de alta una plantilla nueva sin capturar su ID—
2Entrada Única · Vendor CenterMS-01 Catálogo (por el BFF)Pide el plan del alta bajo su familiaAPI-01-023
3MS-01 CatálogoMS-13 Identidad y accesoPide los roles del usuario y los cruza con su matrizAPI-13-001
4Entrada Única · Vendor CenterMS-01 Catálogo (por el BFF)Confirma el plan y abre la solicitud de cambioAPI-01-004
5MS-01 CatálogoBase pimGuarda la solicitud pendiente con su antes y después—
6MS-01 CatálogoMS-14 Avisos y ayudaAvisa a los aprobadores que hay una solicitudAPI-14-005
7Administración del catálogoEntrada Única · Vendor CenterOtro administrador abre su bandeja de solicitudes—
8Entrada Única · Vendor CenterMS-01 Catálogo (por el BFF)Lista las solicitudes pendientes que puede decidirAPI-01-101
9Entrada Única · Vendor CenterMS-01 Catálogo (por el BFF)Abre el cambio campo por campoAPI-01-102
10Entrada Única · Vendor CenterMS-01 Catálogo (por el BFF)Aprueba la solicitudAPI-01-103
11MS-01 CatálogoBase pimAsigna el siguiente EU4 y crea la plantilla activa—
12MS-01 CatálogoEventosAvisa el alta de la plantillacatalog.governance.changed/TEMPLATE_CHANGED
13EventosMS-05 AuditoríaEntrega el cambio para la bitácora por campocatalog.governance.changed/TEMPLATE_CHANGED
14EventosMS-02 ProductoEntrega el cambio: la captura ya puede ofrecerlacatalog.governance.changed/TEMPLATE_CHANGED

3.1 Si el aprobador rechaza

MS-14 Avisos y ayudaBase·pimMS-01 CatálogoEntrada Única · Vendor CenterMS-14 Avisos y ayudaBase·pimMS-01 CatálogoEntrada Única · Vendor CenterBFFAdministración del catálogo1. Rechaza la solicitud con su motivoPOST /api/v2/catalog-change-requests/{changeRequestId}/decision2. Cierra la solicitud rechazada sin tocar el catálogo3. Avisa al solicitante el rechazo y su motivoPOST /internal/notifications/messages4. El solicitante revisa en qué quedó su solicitud5. Lee el recibo con el estado y el motivoGET /api/v2/catalog-receipts/{requestId}BFFAdministración del catálogo
Si el aprobador rechaza

3.2 Cambios que llegan por carga masiva o por la IA

EventosEntrada Única · Vendor CenterMS-14 Avisos y ayudaBase·pimMS-01 CatálogoMS-15 IA y enriquecimientoEventosEntrada Única · Vendor CenterMS-14 Avisos y ayudaBase·pimMS-01 CatálogoMS-15 IA y enriquecimientoBFF1. Propone una plantilla nueva con canal IAPOST /api/v2/catalog-imports2. Valida igual que la pantalla y guarda la carga3. Aplica la carga y abre la solicitudPOST /api/v2/catalog-imports/{id}/apply4. Avisa a Gobierno de Producto la solicitud de la IAPOST /internal/notifications/messages5. Un administrador decide lo que propuso la IAPOST /api/v2/catalog-change-requests/{changeRequestId}/decision6. Avisa la plantilla con su origen IATEMPLATE_CHANGEDBFF
Cambios que llegan por carga masiva o por la IA

3.3 Migración con los ID de P360 y su historia

MS-05 AuditoríaEntrada Única · Vendor CenterBase·pimMS-01 CatálogoMS-03 Migración y convivenciaMS-05 AuditoríaEntrada Única · Vendor CenterBase·pimMS-01 CatálogoMS-03 Migración y convivenciaBFFAdministración del catálogo1. Carga los objetos migrados con su ID de P360POST /internal/governance/bulk-load/{coleccion}2. Guarda sin eventos y ajusta la secuencia al máximo migrado3. Alguien intenta cambiar el ID de una plantilla migradaPOST /api/v2/structures/{id}/nodes/plans4. Rechaza el plan con IMMUTABLE_ID5. Un auditor consulta la historia de la plantilla6. Pide los cambios por campo desde la migraciónGET /api/v2/audit/entities/{entityType}/{entityId}/eventsBFFAdministración del catálogo
Migración con los ID de P360 y su historia

4. Si algo sale mal

  • El aprobador rechaza. La solicitud se cierra como rechazada, el catálogo no cambia y MS-14 avisa al solicitante con el motivo; puede abrir otra solicitud corregida.
  • Alguien cambió el objeto mientras la solicitud esperaba. Al aprobar, MS-01 vuelve a comparar las versiones: si alguna cambió, la solicitud queda en conflicto sin aplicar nada (409 VERSION_CONFLICT) y el solicitante recibe el aviso para pedirla otra vez sobre la versión vigente.
  • Nadie decide la solicitud. A los 23 días MS-14 le recuerda al solicitante y a los aprobadores; a los 30 la solicitud vence sola sin tocar el catálogo y queda en su recibo como vencida.
  • Quien pidió el cambio intenta aprobarlo. La decisión responde 403 AUTHORIZATION_ERROR: nadie aprueba lo que pidió, y la bandeja no le muestra el botón (canDecide en falso).
  • Alguien captura un ID sin permiso o intenta cambiar uno existente. El plan responde 403 AUTHORIZATION_ERROR o 409 IMMUTABLE_ID y no se abre ninguna solicitud; si el ID ya es de otro objeto, 409 ID_ALREADY_EXISTS.

5. APIs

Las que construye esta épica (8)

POST /api/v2/catalog-plans/{planId}/apply · Confirmar un plan del catálogo
CampoValor
APIAPI-01-004 · MS-01 Catálogo
Para quéConfirma cualquier plan de MS-01. Si el cambio pide aprobación (todo lo que define la plantilla: atributos, listas, grupos, árboles, metadatos y configuración), lo deja como solicitud pendiente y no toca el catálogo. Si no la pide (un diccionario así marcado, o una regla según lo que fije FT-PLT-07), lo aplica con su recibo y su aviso.
En esta épicaConfirmar cualquier plan de MS-01: abre la solicitud o aplica directo
Quién la llamaBFF del portal, MS-15 IA y enriquecimiento
PermisoEl mismo usuario o servicio que pidió el plan
CabecerasAuthorization, X-Request-Id, Idempotency-Key
ParámetrosplanId = pln-a41c09
Escribe engovernance_rules, reference_tables, governance_receipts, governance_outbox
Publicacatalog.governance.changed/RULE_CHANGED, catalog.governance.changed/REFERENCE_TABLE_CHANGED
También la usanFT-ACT-01, FT-ARQ-02, FT-CAT-04, FT-CAT-05, FT-IA-03, FT-INT-03, FT-PLT-02, FT-PLT-03, FT-PLT-04, FT-PLT-05, FT-PLT-06, FT-PLT-07, FT-PLT-10, FT-REF-01, FT-REF-02, FT-USR-02

Request

{
  "comment": "Atributo pedido para las licuadoras de alta potencia"
}

Response · 202

{
  "success": true,
  "data": {
    "requestId": "req-8e41a0",
    "status": "PENDING_APPROVAL",
    "changeRequestId": "chg-2a71c4",
    "receiptUrl": "/api/v2/catalog-receipts/req-8e41a0"
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDEl plan no existe o es de otro usuario
409PLAN_EXPIREDPasaron más de 10 minutos desde la vista previa
409VERSION_CONFLICTAlgún objeto cambió después de la vista previa
409IDEMPOTENCY_MISMATCHSe repite la llave de idempotencia con otro plan
409WRITE_DISABLEDP360 todavía es la fuente del catálogo (antes del corte de R1)
GET /api/v2/catalog-change-requests · Bandeja de solicitudes del catálogo
CampoValor
APIAPI-01-101 · MS-01 Catálogo
Para quéLista las solicitudes de cambio del catálogo con filtros por estado, tipo de objeto, canal y área que la pidió. Marca cuáles puede decidir quien llama: nadie decide lo que él mismo pidió.
En esta épicaLa bandeja de solicitudes del catálogo
Quién la llamaBFF del portal
PermisoCAT-E ve las suyas; el aprobador del catálogo ve las que puede decidir
CabecerasAuthorization, X-Request-Id
Parámetrosstatus = PENDING, objectType = TEMPLATE_NODE, channel = PORTAL, requestedByArea = GOBIERNO-PRODUCTO, page = 1, size = 50

Request

null

Response · 200

{
  "success": true,
  "data": {
    "items": [
      {
        "changeRequestId": "chg-2a71c4",
        "status": "PENDING",
        "channel": "PORTAL",
        "objectType": "TEMPLATE_NODE",
        "operation": "CREATE",
        "summary": "Alta de la plantilla «Licuadoras de inmersión» bajo EU3-0398",
        "objectCount": 1,
        "requestedBy": {
          "userId": "usr-1042",
          "area": "GOBIERNO-PRODUCTO"
        },
        "requestedAt": "2027-01-12T15:05:00Z",
        "expiresAt": "2027-02-11T15:05:00Z",
        "canDecide": true
      }
    ],
    "page": 1,
    "size": 50,
    "total": 1
  }
}

Errores

HTTPCódigoCuándo
400VALIDATION_ERRORUn filtro trae un estado, tipo o canal que no existe
GET /api/v2/catalog-change-requests/{changeRequestId} · Detalle de una solicitud de cambio
CampoValor
APIAPI-01-102 · MS-01 Catálogo
Para quéMuestra lo que se pide cambiar, objeto por objeto y campo por campo (antes y después), con su impacto en plantillas y productos, para que el aprobador decida con todo a la vista.
En esta épicaEl detalle de una solicitud, campo por campo
Quién la llamaBFF del portal
PermisoQuien la pidió y los aprobadores del catálogo
CabecerasAuthorization, X-Request-Id
ParámetroschangeRequestId = chg-2a71c4
También la usanFT-IA-04

Request

null

Response · 200

{
  "success": true,
  "data": {
    "changeRequestId": "chg-2a71c4",
    "status": "PENDING",
    "channel": "PORTAL",
    "operation": "CREATE",
    "version": 1,
    "comment": "Familia nueva pedida por Compras Hogar",
    "requestedBy": {
      "userId": "usr-1042",
      "area": "GOBIERNO-PRODUCTO"
    },
    "requestedAt": "2027-01-12T15:05:00Z",
    "expiresAt": "2027-02-11T15:05:00Z",
    "objects": [
      {
        "objectType": "TEMPLATE_NODE",
        "objectId": null,
        "idAssignedOn": "APPROVAL",
        "idPattern": "EU4-{número}",
        "baseVersion": null,
        "diff": [
          {
            "path": "name.es",
            "before": null,
            "after": "Licuadoras de inmersión"
          },
          {
            "path": "parentId",
            "before": null,
            "after": "EU3-0398"
          },
          {
            "path": "keywords",
            "before": null,
            "after": [
              "licuadora de mano",
              "batidora de inmersión"
            ]
          }
        ]
      }
    ],
    "impact": {
      "templates": 1,
      "views": 3,
      "products": 0
    },
    "decision": null
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDLa solicitud no existe o no es visible para quien llama
POST /api/v2/catalog-change-requests/{changeRequestId}/decision · Aprobar o rechazar una solicitud
CampoValor
APIAPI-01-103 · MS-01 Catálogo
Para quéEl aprobador decide. Al aprobar, MS-01 vuelve a comparar las versiones, asigna los ID nuevos, aplica cada objeto con su recibo y publica sus avisos; si algo cambió entretanto, la solicitud queda en conflicto sin aplicar nada. Al rechazar, cierra la solicitud con su motivo.
En esta épicaAprobar o rechazar una solicitud
Quién la llamaBFF del portal
PermisoAprobador del catálogo para ese tipo de objeto; nunca quien pidió la solicitud
CabecerasAuthorization, X-Request-Id, Idempotency-Key, If-Match
ParámetroschangeRequestId = chg-2a71c4
Escribe enattributes, attribute_groups, lovs, lov_values, taxonomies, taxonomy_nodes, template_views, governance_rules, reference_table_defs, reference_tables, id_sequences, governance_receipts, governance_outbox
Publicacatalog.governance.changed/ATTRIBUTE_CHANGED, catalog.governance.changed/LOV_CHANGED, catalog.governance.changed/LOV_VALUE_CHANGED, catalog.governance.changed/TEMPLATE_CHANGED, catalog.governance.changed/TEMPLATE_VIEW_CHANGED, catalog.governance.changed/REFERENCE_TABLE_CHANGED, catalog.governance.changed/RULE_CHANGED, catalog.governance.changed/TAXONOMY_NODE_CHANGED
También la usanFT-IA-04, FT-PLT-02, FT-PLT-03, FT-PLT-04, FT-PLT-05, FT-PLT-06, FT-PLT-07, FT-PLT-09

Request

{
  "decision": "APPROVE",
  "comment": "Revisado contra la guía de familias de cocina"
}

Response · 202

{
  "success": true,
  "data": {
    "requestId": "req-c90d17",
    "status": "ACCEPTED",
    "changeRequestId": "chg-2a71c4",
    "receiptUrl": "/api/v2/catalog-receipts/req-c90d17"
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORQuien llama no puede aprobar ese tipo de objeto o es quien pidió la solicitud
409NOT_EDITABLE_IN_STATUSLa solicitud ya se decidió, se aplicó o venció
409VERSION_CONFLICTAlgún objeto cambió desde que se pidió: la solicitud queda en CONFLICTO y hay que pedirla otra vez
422VALIDATION_ERRORUn rechazo llega sin motivo
GET /api/v2/catalog-receipts/{requestId} · Recibo de una escritura del catálogo
CampoValor
APIAPI-01-034 · MS-01 Catálogo
Para quéDice en qué quedó una escritura confirmada: pendiente de aprobar, aplicada, rechazada, en conflicto o vencida, y qué pasó con cada objeto (con su ID nuevo y su versión).
En esta épicaEl recibo de cualquier escritura del catálogo
Quién la llamaBFF del portal, MS-15 IA y enriquecimiento
PermisoQuien hizo la operación y los aprobadores del catálogo
CabecerasAuthorization, X-Request-Id
ParámetrosrequestId = req-8e41a0
También la usanFT-PLT-07

Request

null

Response · 200

{
  "success": true,
  "data": {
    "requestId": "req-8e41a0",
    "status": "DONE",
    "changeRequestId": "chg-2a71c4",
    "finishedAt": "2027-01-12T18:02:11Z",
    "items": [
      {
        "objectType": "ATTRIBUTE",
        "objectId": "ATR-0003001",
        "result": "APPLIED",
        "version": 1
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDNo existe el recibo o no es de quien llama
POST /internal/governance/bulk-load/{coleccion} · Carga de la migración
CampoValor
APIAPI-01-053 · MS-01 Catálogo
Para quéMS-03 carga por lotes lo que se migra de P360: conserva cada ID de P360, actualiza si la llave ya es del mismo objeto, no publica eventos y, al terminar cada colección, deja la secuencia de ID en el máximo migrado más uno y calcula las vistas efectivas.
En esta épicaLa carga de la migración con los ID de P360
Quién la llamaMS-03 Migración y convivencia
PermisoSólo MS-03 (cuenta de servicio)
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Parámetroscoleccion = taxonomy_nodes
Escribe enattributes, attribute_groups, lovs, lov_values, taxonomies, taxonomy_nodes, template_views, reference_table_defs, reference_tables, governance_rules, categories, brands, id_sequences
También la usanFT-CAT-01, FT-MIG-02, FT-PLT-02, FT-PLT-03, FT-PLT-04, FT-PLT-06, FT-REF-01, FT-REF-02

Request

{
  "runId": "mig-run-0007",
  "batch": 12,
  "documents": [
    {
      "_id": "EU4-0412",
      "taxonomy": "PRODUCT",
      "level": 4,
      "parentId": "EU3-0398",
      "name": {
        "es": "Licuadoras"
      },
      "keywords": [
        "licuadora",
        "blender"
      ],
      "status": "ACTIVE",
      "attributeBindings": [],
      "legacy": {
        "owner": "P360"
      }
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "runId": "mig-run-0007",
    "batch": 12,
    "upserted": 1,
    "rejected": 0,
    "items": [
      {
        "_id": "EU4-0412",
        "result": "CREATED"
      }
    ],
    "sequenceAfterLoad": {
      "TEMPLATE_NODE:EU4": "EU4-4087"
    }
  }
}

Errores

HTTPCódigoCuándo
409IMMUTABLE_IDLa llave ya existe y es de otro tipo de objeto: el registro se rechaza y va a cuarentena de MS-03
422VALIDATION_ERRORUn registro no cumple el modelo (sin padre, lista inactiva, tipo desconocido)
409IDEMPOTENCY_MISMATCHEl mismo lote llega otra vez con contenido distinto
GET /api/v2/catalog-permissions · Matriz de permisos del catálogo
CampoValor
APIAPI-01-109 · MS-01 Catálogo
Para quéMuestra la tabla con la que MS-01 decide los permisos de dominio del catálogo: por rol del directorio, qué puede hacer (consultar, proponer, aprobar, mover, desligar, capturar un ID) en cada tipo de objeto y en qué negocios. Se guarda como un diccionario de MS-01 cuya área dueña es Seguridad.
En esta épicaLa matriz de permisos del catálogo: rol, tipo de objeto, acciones y negocios
Quién la llamaBFF del portal
PermisoSeguridad y Gobierno de Producto (consulta)
CabecerasAuthorization, X-Request-Id
ParámetrosroleId = GOBIERNO_PRODUCTO, object = ATTRIBUTE

Request

null

Response · 200

{
  "success": true,
  "data": {
    "matrixVersion": 8,
    "version": 3,
    "updatedAt": "2027-01-08T16:00:00Z",
    "rows": [
      {
        "roleId": "GOBIERNO_PRODUCTO",
        "object": "ATTRIBUTE",
        "actions": [
          "READ",
          "PROPOSE",
          "APPROVE",
          "CAPTURE_ID"
        ],
        "businesses": [
          "MER",
          "SUB",
          "MKP"
        ]
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORQuien llama no es de Seguridad ni de Gobierno de Producto
POST /api/v2/catalog-permissions/plans · Plan de carga de la matriz de permisos del catálogo
CampoValor
APIAPI-01-110 · MS-01 Catálogo
Para quéRevisa sin escribir la hoja del catálogo de la matriz firmada (rol, tipo de objeto, acciones y negocios): valida contra MS-13 que cada rol exista (API-13-005) y dice qué permisos se agregan, cambian o quitan. Se confirma con API-01-004 y, como todo cambio de permisos, pide aprobación de otra persona.
En esta épicaCargar con vista previa la hoja del catálogo de la matriz firmada
Quién la llamaBFF del portal
PermisoSeguridad
CabecerasAuthorization, X-Request-Id, Idempotency-Key, If-Match
También la usanFT-USR-02

Request

{
  "version": 3,
  "matrixVersion": 9,
  "rows": [
    {
      "roleId": "CATEGORY",
      "object": "CATEGORY",
      "actions": [
        "CREATE",
        "UPDATE",
        "MOVE",
        "UNLINK",
        "APPROVE"
      ],
      "businesses": [
        "MER",
        "MKP",
        "SUB"
      ]
    },
    {
      "roleId": "GOBIERNO_PRODUCTO",
      "object": "ATTRIBUTE",
      "actions": [
        "READ",
        "PROPOSE",
        "APPROVE",
        "CAPTURE_ID"
      ],
      "businesses": [
        "MER",
        "SUB",
        "MKP"
      ]
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "planId": "pln-61f2c8",
    "expiresAt": "2027-01-08T16:10:00Z",
    "requiresApproval": true,
    "summary": {
      "rowsAdded": 0,
      "rowsChanged": 1,
      "rowsRemoved": 0
    },
    "unknownRoles": [],
    "changes": [
      {
        "roleId": "CATEGORY",
        "object": "CATEGORY",
        "before": [
          "CREATE",
          "UPDATE",
          "MOVE",
          "UNLINK"
        ],
        "after": [
          "CREATE",
          "UPDATE",
          "MOVE",
          "UNLINK",
          "APPROVE"
        ]
      }
    ],
    "applyUrl": "/api/v2/catalog-plans/pln-61f2c8/apply"
  }
}

Errores

HTTPCódigoCuándo
422VALIDATION_ERRORUn rol no existe en el directorio de MS-13, o una acción o un tipo de objeto no existen
403AUTHORIZATION_ERRORQuien llama no es de Seguridad
409VERSION_CONFLICTLa matriz cambió desde que se leyó

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-01-023POST /api/v2/structures/{id}/nodes/plansEjemplo de plan: el alta de un nodo de plantillaFT-PLT-05 · Taxonomía de plantillas por familia, metadatos de…
API-01-031POST /api/v2/catalog-importsLa IA propone por la misma carga que valida la pantallaFT-PLT-09 · Carga masiva de configuración de plantillas con…
API-01-032POST /api/v2/catalog-imports/{id}/applyAplicar la carga: abre la solicitud con su canalFT-PLT-09 · Carga masiva de configuración de plantillas con…
API-13-001GET /internal/identity/permissions?userId=Los roles y capacidades del usuario, con caché, para decidir los permisos de dominio del catálogoFT-USR-01 · Identidad y autenticación de usuarios internos…
API-13-005GET /api/v2/rolesValidar que los roles de la matriz existan en el directorioFT-USR-02 · Matriz de roles y permisos por módulo, acción, negocio y…
API-14-005POST /internal/notifications/messagesAvisar a aprobadores y solicitantesFT-RAC-05 · Estatus del producto y motivos visibles para seller y…
API-05-001GET /api/v2/audit/entities/{entityType}/{entityId}/eventsLa historia por campo de un objeto del catálogoFT-ARQ-02 · Bitácora inmutable y versionado de producto, plantilla y…

6. Eventos

Publica

EventoCuándoQuién lo consume
catalog.governance.changed/TEMPLATE_CHANGEDSe aprueba el alta o el cambio de una plantilla, también las que propone la IAFT-ARQ-02, FT-PLT-08

Consume

EventoPara quéQuién lo publica
catalog.governance.changed/TEMPLATE_CHANGEDMS-05 guarda en la bitácora el antes y el después de cada campo, con el actor, el canal y la solicitudesta misma épica
catalog.governance.changed/TEMPLATE_CHANGEDMS-02 refresca su copia del catálogo y la captura ya puede ofrecer la plantillaesta misma épica

7. Datos

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

ColecciónDueñoQué guardaEsta épica
governance_change_requestsMS-01Cada solicitud de cambio del catálogo: qué objetos toca, el antes y el después por campo, el canal (pantalla, carga, API, IA o migración), quién la pidió y quién la decidió, su estado (pendiente, aprobada, rechazada, aplicada, en conflicto o vencida) y su recibo.escribe
taxonomy_nodesMS-01Plantillas y nodos de grupo de artículo, con la configuración de atributos de cada plantilla.escribe
template_viewsMS-01La vista efectiva ya resuelta por plantilla y negocio: qué atributos pide y cuáles son obligatorios.escribe
id_sequencesMS-01El siguiente identificador de plantillas y catálogos.escribe
governance_receiptsMS-01El recibo de cada escritura confirmada en el catálogo (antes operation_receipts).escribe
governance_outboxMS-01Los cambios del catálogo que esperan salir como evento (antes outbox).escribe
taxonomiesMS-01Los árboles: plantillas, grupos de artículo y sitios web.lee
taxonomy_nodesMS-01Plantillas y nodos de grupo de artículo, con la configuración de atributos de cada plantilla.lee
attributesMS-01Cada atributo: tipo, lista, restricciones, grupos e identificadores externos.lee

8. Historias que cubre

HistoriaPrioridadCómo la cubre
FT-PLT-01·H1 · IDs establesP1pasos 1, 2, 11; flujo «Migración con los ID de P360 y su historia»; API-01-023, API-01-053
FT-PLT-01·H2 · Nada surte efecto sin aprobaciónP1pasos 4, 5, 6, 7, 8, 9, 10, 11; flujo «Cambios que llegan por carga masiva o por la IA», «Si el aprobador rechaza»; API-01-004, API-01-101, API-01-102, API-01-103
FT-PLT-01·H3 · Historia por campoP2pasos 12, 13; flujo «Migración con los ID de P360 y su historia»; API-05-001
FT-PLT-01·H4 · Sólo roles autorizadosP2pasos 3; API-13-001, API-01-109, API-01-110, API-13-005

9. Decisiones de esta épica

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

  • D-PLT-01-1. Toda escritura de lo que define la plantilla (atributos, listas, grupos, árbol, metadatos y configuración), venga de pantalla, carga masiva, API o IA, queda como solicitud en una colección propia de MS-01 y surte efecto sólo cuando otra persona con permiso la aprueba. Nadie aprueba lo que pidió. Por qué: La ERF 1.1 §3.4 pide que nada surta efecto sin aprobación y DEC-ARQ-12 lo metió al alcance. El plan dura minutos y no sirve para esperar una aprobación de días; guardar la solicitud aparte del objeto evita versiones a medias en el catálogo vigente. Se apoya en DEC-ARQ-12, DEC-PLT-05, PD-01.
  • D-PLT-01-2. Qué pide aprobación lo fija una política de MS-01 por tipo de objeto. Lo que el PIM no gobierna no la pide: los catálogos que manda SAP (API-01-050 a 052) y la carga de la migración (API-01-053) se aplican directo con su recibo. Cada diccionario y cada tipo de regla dicen en su definición si la piden (FT-REF-01 y FT-PLT-07). Por qué: SAP es el dueño de sus catálogos: aprobar en el PIM lo que SAP ya decidió sólo crea desfases. Una sola política evita que cada pantalla invente su regla. Se apoya en DUD-21, DUD-23, DEC-ARQ-12.
  • D-PLT-01-3. Los ID de P360 se conservan y ningún ID de plantilla, atributo o lista se modifica. Los nuevos salen de id_sequences con el formato de hoy (EU{nivel+1}-{número} en plantillas) y se asignan al aprobar; capturar un ID al crear exige un permiso propio. Si una carga trae un ID existente, actualiza cuando es el mismo tipo de objeto y falla con ID_ALREADY_EXISTS si es otro. Por qué: Entrada Única, Foro, SAP y la tienda resuelven sus referencias con esos ID; cambiarlos exigiría equivalencias en cada consumidor. Se apoya en PD-16, DEC-PLT-06, DUD-18.
  • D-PLT-01-4. La historia por campo la guarda sólo MS-05, a partir de los eventos de catalog.governance.changed, que llevan el antes y el después, el actor, el canal y la solicitud. MS-01 no lleva bitácora propia. Lo migrado empieza su historia en la carga: la de P360 no se migra. Por qué: Un dueño para la bitácora. P360 no guarda el valor anterior ni el nuevo, así que no hay historia que traer. Se apoya en DEC-ARQ-09, PD-05, ADR-12.
  • D-PLT-01-5. Los permisos de dominio del catálogo los decide MS-01: cruza los roles del usuario que da el directorio (API-13-001, con caché) con su matriz del catálogo (rol, tipo de objeto, acción y negocio), que Seguridad carga de la hoja firmada (API-01-110) y que se guarda como un diccionario de MS-01. El BFF sólo decide los de pantalla. Sin matriz firmada no se concede ningún permiso por suposición: la operación se niega. Por qué: Decisión 19 del backend compartido que adopta ADR-12: los permisos de dominio viven en el servicio dueño con los roles del directorio. La matriz no se inventa; la trae FT-USR-02. Se apoya en ADR-12, DEC-PLT-09, DUD-22.
  • D-PLT-01-6. Hasta el corte del catálogo en R1, P360 es la fuente: MS-01 sólo recibe la carga de MS-03 y responde WRITE_DISABLED a toda escritura de pantalla. Desde el corte, P360 congela sus plantillas y el PIM es la única fuente. Por qué: Escribir en los dos lados es una doble escritura que sólo cubre una parte del catálogo; congelar cuesta poco y es lo que recomienda el diseño (opción A). Se apoya en PD-12, DEC-PLT-13.
  • D-PLT-01-7. Una solicitud pendiente vence a los 30 días sin decisión, con recordatorio a los 23. Al aprobar, MS-01 vuelve a validar contra la versión de cada objeto y, si alguno cambió, la deja en conflicto sin aplicar nada. Por qué: Nunca se aplica un cambio sobre una base distinta de la que vio el aprobador, y las solicitudes olvidadas no se acumulan. Se apoya en DEC-PLT-05.

Qué falta decidir

IDQué falta
DUD-22Seguridad con Gobierno de Producto firman la matriz: qué rol propone, quién captura un ID y quién aprueba cada tipo de objeto.
PD-16Arquitectura con Gobierno de Producto ratifica que ningún ID se modifica (propuesta del 17-oct); un atributo mal nombrado se corrige con uno nuevo.
DUD-18Gobierno de Producto fija qué campos definen «el mismo objeto» por tipo; aquí se usa el tipo de objeto más su ID.
PD-12Arquitectura con Gobierno de Datos confirma el orden de corte; aquí se asume congelar plantillas en P360 desde el corte de R1.

Fuentes

  1. [D] trazabilidad/features/FT-PLT-01-fundamentos-de-gobierno-de-plantillas.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.