Capa de interoperabilidad · Prueba técnica de arquitectura

ADR-025: cómo recibe el OMS la dirección de entrega sin sacar datos personales a Kafka

Aceptado el 15/11/2026 por Andrés con la opción A (propuesto el 11/11/2026 por el agente; toca la regla 2 de `CLAUDE.md` y ADR-010). Complementa ADR-010 (gRPC pasa de un punto a dos). Sin implementar al 15/11/2026; hasta entonces el registro en el OMS sale sin dirección.

Contexto

El OMS legado necesita la dirección de entrega y el contacto para despachar. Esos datos viven solo en order-service, cifrados por campo (docs/to-be/02-dominios-y-servicios.md, 08-seguridad.md). La regla 5 prohíbe datos personales en eventos, y el comando CreateOmsOrder viaja por Kafka. El contrato ya da la dirección de la respuesta, en la descripción de OrderEvent: "Quien necesite la dirección la pide a order-service con el orderId". Pero no dice por qué vía, y ninguna operación la ofrece. Hoy (carril f4-oms-webhooks) la orden se registra en el OMS sin dirección.

Las opciones chocan con alguna regla: la 1 (solo los adaptadores hablan con el legado), la 2 (la única llamada síncrona interna es de order-service a inventory-service) o la 5 (ningún dato personal en eventos).

Opciones

Opción A favor En contra
A. Ticket de reclamo (claim check): el comando lleva solo orderId; oms-adapter pide la dirección a order-service por gRPC (GetFulfillmentDetails), autorizado solo para su identidad de carga Los datos personales nunca tocan Kafka; un solo dueño; con mTLS y AuthorizationPolicy, solo oms-adapter llega; patrón conocido (Claim Check, de Enterprise Integration Patterns) Una segunda llamada síncrona interna, que pide ampliar ADR-010; el registro en el OMS depende de que order-service responda (se reintenta como cualquier fallo)
B. La dirección va en el comando, cifrada con una llave que solo oms-adapter puede descifrar Sigue asíncrono, sin llamada nueva Datos personales, aunque cifrados, en un tópico con retención de días y en sus reintentos y DLQ; rompe la letra de la regla 5; borrar un dato exige rotar o destruir la llave
C. order-service registra la orden en el OMS directamente Sin piezas nuevas Rompe la regla 1: un servicio de dominio habla con el legado
D. El OMS toma la dirección del CRM por customerId Sin datos personales en la capa Una compra sin cuenta no tiene cliente en el CRM, y la dirección de una orden no es la del perfil

Decisión propuesta

Opción A.

  1. order-service expone el servicio gRPC interno andesretail.orders.v1.FulfillmentDetails/GetFulfillmentDetails(orderId), que devuelve el destinatario, la dirección y el contacto de la orden, descifrados en memoria y nunca escritos en el log.
  2. Acceso: solo la identidad de carga de oms-adapter llega a esa operación, por la AuthorizationPolicy de la malla (platform/mesh/) y por una segunda comprobación en el servicio.
  3. El adaptador la llama al procesar CreateOmsOrder, entrega la dirección al OMS y no la guarda. Si order-service no responde, el comando sigue la política de reintento y DLQ del contrato.
  4. Registro: cada lectura queda en andes.audit.v1, con quién, qué orden y cuándo, sin los datos.
  5. ADR-010: gRPC pasa de "un solo punto" a dos: order-service hacia inventory-service, y oms-adapter hacia order-service para este dato.

Qué se sacrifica

Si Andrés no la aprueba

Mientras no haya decisión, el registro en el OMS sale sin dirección, y eso es un hueco del demo que el entregable debe decir. La alternativa de menor costo es B, que exige reescribir la regla 5 como "ningún dato personal en claro".