23 Oct, 2026

modern-sap-lab: Clean Core no es sacar código de SAP, es decidir dónde pertenece

modern-sap-lab: Clean Core no es sacar código de SAP, es decidir dónde pertenece

Clean Core no es sacar código de SAP, es decidir dónde pertenece

Es fácil resumir Clean Core diciendo que debemos evitar modificar el núcleo de SAP.

La dificultad empieza después.

Porque en un proyecto real alguien tiene que decidir:

  • qué debe resolver SAP;
  • qué pertenece al negocio específico de la empresa;
  • dónde debe residir esa lógica;
  • quién es propietario de cada dato;
  • cómo se conectan las distintas piezas;
  • y cómo evitar que el desacoplamiento termine convirtiéndose simplemente en otra arquitectura difícil de mantener.

Ésa es la cuestión que estoy explorando en modern-sap-lab.

No quería construir una colección de ejemplos independientes de CDS, RAP o CAP.

Quería partir de un problema empresarial suficientemente realista como para que las decisiones de arquitectura importasen.

Y construirlo.

Un caso de negocio deliberadamente sencillo

El laboratorio modela una empresa de intermediación comercial.

La empresa trabaja con distintos fabricantes, mayoristas o distribuidores —a los que denomino Principal— que venden sus productos directamente a sus clientes.

La relación básica es:

Cliente final
    │
    │ compra mercancía
    ▼
Principal
    │
    │ paga una comisión
    ▼
Empresa intermediaria

La empresa intermediaria participa en la operación comercial, pero hay algo importante:

no compra la mercancía, no la almacena y no la vende.

El Principal sirve directamente al cliente.

Posteriormente, la empresa intermediaria factura al Principal el servicio prestado según las operaciones realmente realizadas.

Parece un detalle funcional.

En realidad es la decisión que condiciona buena parte de la arquitectura.

El producto que técnicamente puedo crear en SAP pero no quiero crear

Supongamos que uno de nuestros Principal vende este producto:

Principal: ACME
Referencia: XZ-150
Descripción: Motor industrial 150 W

Podría crear XZ-150 como material en SAP.

La cuestión es:

¿por qué debería hacerlo?

Mi empresa:

  • no compra ese motor;
  • no lo almacena;
  • no controla su stock;
  • no lo vende;
  • no lo expide.

Que SAP participe en algún momento del proceso no convierte automáticamente todos los conceptos del proceso en conceptos de nuestro ERP.

Ésta es probablemente la regla que mejor resume el laboratorio:

SAP sólo debe conocer aquello que necesita conocer.

No porque SAP no pueda almacenar más.

Precisamente porque puede.

La capacidad técnica para implementar algo dentro de una plataforma no constituye por sí misma una razón arquitectónica para hacerlo.

Clean Core no significa sacar todo fuera de SAP

El extremo contrario tampoco tendría sentido.

Si la empresa intermediaria necesita emitir una factura por sus servicios, no quiero construir otro sistema de facturación.

SAP ya sabe resolver:

  • Business Partner;
  • facturación;
  • fiscalidad;
  • condiciones de pago;
  • vencimientos;
  • contabilización;
  • cuentas a cobrar;
  • integración financiera.

Eso pertenece naturalmente al ERP.

Por tanto, la idea no es vaciar SAP.

Es establecer una frontera:

DOMINIO DE INTERMEDIACIÓN

productos
tarifas
ofertas
pricing
pedidos
entregas
comisiones
liquidaciones

             │
             │ contrato
             ▼

SAP S/4HANA

Business Partner
Billing
Tax
Payment Terms
FI

La aplicación de intermediación deberá determinar qué debe facturarse.

SAP deberá determinar cómo se factura y contabiliza.

La diferencia es pequeña al escribirla.

Arquitectónicamente es enorme.

El dominio debe seguir siendo el dominio

A partir de ahí aparece el segundo principio del laboratorio.

Las reglas de negocio deben tener un propietario claro.

Por ejemplo, un Principal puede atravesar diferentes estados:

INACTIVE
   │
   ▼
REVIEW
  ├────────► ACTIVE
  │
  └────────► INACTIVE

ACTIVE
  ├────────► INACTIVE
  └────────► SUSPENDED

SUSPENDED
   │
   └────────► ACTIVE

Podría implementar estas reglas en la aplicación que consume SAP.

No lo hago.

Actualmente RAP ya protege las transiciones en el backend.

Por ejemplo:

INACTIVE -> SubmitForReview -> REVIEW
REVIEW   -> Approve         -> ACTIVE
REVIEW   -> Reject          -> INACTIVE
ACTIVE   -> Suspend         -> SUSPENDED
SUSPENDED -> Reactivate     -> ACTIVE

Y también rechaza transiciones inválidas.

La interfaz puede ofrecer un botón.

CAP puede publicar una operación.

Pero ninguno de los dos debe decidir si esa transición es válida.

Esa decisión pertenece al dominio.

CAP como fachada, no como segundo backend de negocio

Ésta ha sido otra decisión importante.

CAP proporciona una fachada adecuada para consumidores externos.

Actualmente el laboratorio ya expone desde CAP recursos como:

/api/intermediation/Principals
/api/intermediation/PrincipalProducts

y las acciones del ciclo de vida de Principal.

Pero CAP no reproduce la máquina de estados.

Las acciones se delegan a RAP.

La cadena conceptual es:

Consumidor
    │
    ▼
CAP
    │
    │ contrato / forwarding
    ▼
RAP
    │
    │ reglas de dominio
    ▼
Persistencia

Esto permite que mañana puedan existir distintos consumidores:

  • una aplicación web;
  • una aplicación móvil;
  • un portal para clientes;
  • procesos de integración;
  • otros servicios;
  • eventualmente otros canales.

Sin convertir cada canal en propietario de las reglas.

Ya no es sólo un diagrama

Cuando planteé inicialmente modern-sap-lab, buena parte de todo esto era diseño.

Ahora ya hay una parte que puede comprobarse.

En ABAP Cloud están implementados los primeros elementos del dominio mediante CDS y RAP.

Principal dispone de comportamiento y ciclo de vida.

PrincipalProduct incorpora reglas como:

  • el Principal debe existir;
  • el código debe ser único dentro del Principal;
  • el código tiene un formato válido;
  • la entrada se normaliza a mayúsculas;
  • determinadas propiedades no pueden modificarse libremente.

Por ejemplo:

abc-001

puede introducirse de esa forma y persistirse de forma canónica como:

ABC-001

mientras que:

abc_01

es rechazado porque _ no pertenece al formato permitido.

Esto puede parecer un detalle menor.

Pero es precisamente lo que me interesa del ejercicio: colocar la regla en el lugar adecuado una vez y hacer que todos los consumidores la respeten.

RAP y CAP conectados mediante contrato

El servicio RAP dispone también de un Service Binding OData V4.

Su $metadata real se utiliza para generar en CAP el modelo del servicio remoto.

La cadena que ya está validada a nivel de contrato es:

RAP
 │
 ▼
OData V4 Service Binding
 │
 ▼
$metadata / EDMX
 │
 ▼
cds import
 │
 ▼
modelo remoto CAP
 │
 ▼
IntermediationService

Esto tiene una propiedad que considero especialmente importante.

CAP no necesita conocer cómo está implementado internamente el dominio ABAP.

Necesita conocer su contrato.

Y eso permite evolucionar las capas con mucha más independencia.

Incluso los límites del Trial enseñan arquitectura

El laboratorio también se ha encontrado ya con algo que normalmente no aparece en el primer diagrama de una solución:

la realidad de la plataforma.

Para probar la cadena autenticada se ha configurado:

Cadena de autenticación

La identidad llega hasta CAP.

CAP resuelve la Destination.

La petición alcanza realmente el sistema ABAP.

Y entonces aparece el límite actual: el plan compartido de ABAP Trial no permite materializar y administrar de la misma forma el Communication Arrangement necesario para ese Web API personalizado, por lo que UCON bloquea la llamada.

La reacción más sencilla habría sido deformar la arquitectura hasta conseguir que la demo funcionase.

No lo he hecho.

La integración completa mediante principal propagation se validará cuando disponga de un entorno ABAP privado con las capacidades necesarias.

Mientras tanto, RAP y CAP continúan evolucionando desacoplados mediante su contrato.

Para mí también eso forma parte de Clean Core:

una limitación del entorno de desarrollo no debería obligarnos a introducir una mala decisión en la arquitectura.

El siguiente bloque ya ha empezado: tarifas

El laboratorio ha avanzado ya al siguiente problema del dominio.

Las tarifas.

Cada Principal podrá disponer de tarifas con periodos de vigencia.

Una tarifa tendrá una cabecera:

Principal
Código de tarifa
Nombre
Válida desde
Válida hasta
Moneda

y diferentes posiciones:

Producto
Precio unitario
Comisión

El modelo base de RAP ya está iniciado como un Business Object compuesto Tariff -> TariffItem.

Y aquí vuelven a aparecer preguntas que no son simplemente técnicas.

¿Qué ocurre cuando recibimos hoy una tarifa que entrará en vigor dentro de tres meses?

¿Qué tarifa corresponde a un pedido realizado ayer?

¿Puede haber dos tarifas solapadas?

¿Qué ocurre si una oferta atraviesa el cambio entre dos tarifas?

¿Debe conservar un pedido el precio recalculado en cada consulta o una fotografía de las condiciones con las que fue creado?

Esas preguntas acabarán transformándose en código.

Pero el código debería ser la consecuencia de haberlas contestado primero.

Hacia dónde puede crecer

El objetivo inmediato sigue siendo construir el proceso completo de intermediación por bloques.

Los Principal no tienen por qué utilizar SAP

Dominio de intermediación

Una evolución razonable sería:

Cuando esa cadena exista, el laboratorio dejará de ser únicamente un conjunto de ejercicios SAP.

Tendrá un proceso empresarial completo.

Y entonces aparecen posibilidades bastante más interesantes.

Éste es otro requisito deliberado del diseño.

Una empresa que nos envíe su catálogo o sus tarifas podría utilizar SAP.

O Microsoft Dynamics.

O un ERP propio.

O simplemente generar un CSV.

El dominio no debería depender de ello.

Por eso la arquitectura contempla una capa de integración capaz de admitir diferentes mecanismos:

SAP Integration Suite puede asumir progresivamente responsabilidades como:

  • conectividad;
  • transformación;
  • routing;
  • seguridad;
  • reintentos;
  • monitorización;
  • adaptación de protocolos.

Capa de integración

Pero no debería decidir qué tarifa corresponde a un pedido.

Eso sigue siendo negocio.

De laboratorio a plataforma

Si el modelo continúa creciendo, las mismas fronteras permitirían evolucionarlo mucho más.

Podríamos incorporar:

  • onboarding de nuevos Principal;
  • distintos canales de entrada;
  • importación masiva de catálogos;
  • versionado de tarifas;
  • promociones más complejas;
  • pedidos multicanal;
  • reconciliación automática de entregas;
  • tratamiento de discrepancias;
  • liquidaciones periódicas;
  • trazabilidad completa de comisiones;
  • integración financiera con S/4HANA;
  • analítica operacional;
  • eventos de negocio;
  • nuevos portales o aplicaciones sin trasladar el dominio a esos canales.

Incluso podríamos llegar a sustituir componentes en el futuro sin tener que rediseñar todo el sistema, siempre que conservemos correctamente los contratos y la propiedad de las responsabilidades.

Eso es mucho más interesante para mí que intentar predecir hoy todas las funcionalidades que algún día podría necesitar la aplicación.

Clean Core también es integración

Hay además una evolución interesante en la propia estrategia de SAP.

Clean Core ya no puede entenderse únicamente como una cuestión de extensibilidad.

Una extensión podría estar perfectamente desacoplada de S/4HANA y, sin embargo, dejar detrás una colección de integraciones punto a punto, APIs inestables y dependencias difíciles de actualizar.

Tendríamos un core aparentemente limpio y un paisaje alrededor imposible de mantener.

Por eso la integración, los contratos y el uso de interfaces estables son también parte de la ecuación.

Para este laboratorio significa que no basta con decir:

“esto está fuera de S/4”

También hay que poder responder:

¿Cómo se comunica?
¿Quién depende de quién?
¿Qué contrato existe?
¿Quién es propietario del dato?
¿Qué ocurre si una pieza cambia?

El objetivo real de modern-sap-lab

No estoy intentando demostrar que sé crear una CDS View.

Ni que puedo implementar un Business Object RAP.

Ni que CAP puede consumir OData.

Todo eso es necesario, pero no es el propósito.

Lo que quiero recorrer es el proceso completo:

  1. entender un problema empresarial;
  2. identificar sus reglas;
  3. definir los límites del dominio;
  4. asignar responsabilidades;
  5. reutilizar aquello que SAP ya resuelve bien;
  6. evitar introducir en el ERP conceptos que no le pertenecen;
  7. construir contratos entre componentes;
  8. implementar cada parte con la tecnología adecuada;
  9. probar las decisiones;
  10. detectar cuándo la realidad contradice el diseño;
  11. y modificar el diseño sólo cuando exista una razón arquitectónica para hacerlo.

La tecnología irá cambiando.

Los frameworks también.

El problema de fondo permanecerá.

Porque Clean Core, al menos como yo lo entiendo, no empieza cuando elegimos entre ABAP Cloud, CAP o Integration Suite.

Empieza antes.

Con una pregunta mucho más sencilla:

¿Dónde pertenece realmente esta responsabilidad?

Ésa es la pregunta que seguirá guiando modern-sap-lab a medida que el laboratorio avance desde los primeros maestros hasta tarifas, pricing, pedidos, entregas, liquidaciones y la integración final con SAP S/4HANA.